Tk Source Code

Changes On Branch core-8-6-branch
Login

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

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

This is equivalent to a diff from 32a9cba0 to 742854d7

2024-12-19
12:26
Fix [a0d6ef020b]: Documentation bugs check-in: 6c685985 user: jan.nijtmans tags: core-8-branch
12:07
Fix [a0d6ef020b]: Documentation bugs Leaf check-in: 742854d7 user: jan.nijtmans tags: core-8-6-branch
11:58
(cherry-pick): Fix [844c0be72d]: Menu entry underline does not consider activeborderwidth. check-in: 9eb91f76 user: jan.nijtmans tags: core-8-6-branch
2020-10-27
07:08
Rename "trunk" to "main". Add "trunk" propagating tag for backwards compatibility check-in: 0f77b70d user: jan.nijtmans tags: trunk, main
01:25
Merge 8.6 Closed-Leaf check-in: 32a9cba0 user: marc_culler tags: trunk
2020-10-26
08:58
Merge 8.6 check-in: 88e0ce57 user: jan.nijtmans tags: trunk
2020-10-25
20:11
Adjustment for Sierra. Closed-Leaf check-in: 77a51c32 user: culler tags: bug-5cc72e002c

Changes to .fossil-settings/encoding-glob.
1
2


3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
10
11


+
+







win/buildall.vc.bat
win/makefile.vc
win/mkd.bat
win/rmd.bat
win/rules-ext.vc
win/rules.vc
win/targets.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
35
36
37

16
17
18
19
20
21
22

23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40







-
+



-
+
+
+










+
*/Makefile
*/autom4te.cache
*/config.cache
*/config.log
*/config.status
*/tkConfig.sh
*/wish*
*/tktest*
*/tktest
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk_*.zip
*/libtk*.zip
*/tkUuid.h
doc/man.macros
html
macosx/configure
win/Debug*
win/Release*
win/*.manifest
win/nmhlp-out.txt
win/nmakehlp.out
unix/tk.pc
unix/Tk-Info.plist
unix/Wish-Info.plist
unix/Credits.html
Added .github/ISSUE_TEMPLATE.md.



1
2
3
+
+
+
Important Note
==========
Please do not file issues with Tk on Github. They are unlikely to be noticed in a timely fashion. Tk issues are hosted in the [tk fossil repository on core.tcl-lang.org](https://core.tcl-lang.org/tk/tktnew); please post them there.
Added .github/PULL_REQUEST_TEMPLATE.md.



1
2
3
+
+
+
Important Note
==========
Please do not file pull requests with Tk on Github. They are unlikely to be noticed in a timely fashion. Tk issues (including patches) are hosted in the [tk fossil repository on core.tcl-lang.org](https://core.tcl-lang.org/tk/tktnew); please post them there.
Added .github/workflows/linux-build.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
name: Linux
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
defaults:
  run:
    shell: bash
    working-directory: tk/unix
env:
  ERROR_ON_FAILURES: 1
jobs:
  build:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
          - "clang"
        config:
          - ""
          - "--disable-shared"
          - "--disable-xft"
          - "--disable-xss"
          - "--enable-symbols"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 8.6
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install tcl8.6-dev libxss-dev libxft-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT --with-tcl=/usr/lib/tcl8.6" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
          echo "TOOL_DIR=$(cd tcl/tools;pwd)" >> $GITHUB_ENV
          echo "BUILD_CONFIG_ID=$OPTS" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.config }}
          COMPILER: ${{ matrix.compiler }}
          OPTS: ${{ matrix.compiler }}${{ matrix.config }}
      - name: Configure (opts=${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Build Test Harness
        run: |
          make tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Test-Drive Installation
        run: |
          make install || {
            echo "::error::Failure during Install"
            exit 1
          }
      - name: Create Distribution Package
        run: |
          make dist || {
            echo "::error::Failure during Distribute"
            exit 1
          }
      - name: Convert Documentation to HTML
        run: |
          make html-tk TOOL_DIR=$TOOL_DIR || {
            echo "::error::Failure during Distribute"
            exit 1
          }
      - name: Discover Version ID
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        run: |
          cd /tmp/dist
          echo "VERSION=`ls -d tk* | sed 's/tk//'`" >> $GITHUB_ENV
      - name: Upload Source Distribution
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        uses: actions/upload-artifact@v4
        with:
          name: Tk ${{ env.VERSION }} Source distribution (snapshot)
          path: |
            /tmp/dist/tk*
            !/tmp/dist/tk*/html/**
      - name: Upload Documentation Distribution
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        uses: actions/upload-artifact@v4
        with:
          name: Tk ${{ env.VERSION }} HTML documentation (snapshot)
          path: /tmp/dist/tk*/html
  test:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        compiler:
          - "gcc"
        config:
          - ""
          - "--disable-xft"
          - "--enable-symbols"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install tcl8.6-dev libxss-dev libxft-dev xvfb
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT --with-tcl=/usr/lib/tcl8.6" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.config }}
          COMPILER: ${{ matrix.compiler }}
      - name: Configure ${{ matrix.config }}
        run: |
          ./configure $CFGOPT "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          xvfb-run --auto-servernum make test-classic | tee out-classic.txt
          xvfb-run --auto-servernum make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 10
Added .github/workflows/mac-build.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
name: macOS
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
env:
  ERROR_ON_FAILURES: 1
jobs:
  xcode:
    runs-on: macos-13
    defaults:
      run:
        shell: bash
        working-directory: tk/macosx
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Prepare checked out repositories
        run: |
          touch tk/generic/tkStubInit.c
          mkdir build
          echo "BUILD_DIR=`cd build && pwd`" >> $GITHUB_ENV
          echo "DESTDIR=`cd build && pwd`" >> $GITHUB_ENV
        working-directory: .
      - name: Build Tcl
        run: |
          make all
        working-directory: tcl/macosx
      - name: Build
        run: |
          make all install || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          make test | tee out.txt
          nmatches=$( grep -c "Failed	0" out.txt )
          if [ $nmatches -lt 4 ]
          then
            echo "::error::Failure during Test"
            exit 1
          fi
        timeout-minutes: 30
  clang:
    runs-on: macos-13
    strategy:
      matrix:
        symbols:
          - 'no'
          - 'mem'
        options:
          - '--enable-aqua'
          - '--disable-aqua'
    defaults:
      run:
        shell: bash
        working-directory: tk/unix
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Prepare checked out repositories
        env:
          SET_DISPLAY: ${{ contains(matrix.options, '--disable-aqua') }}
        run: |
          touch ../generic/tkStubInit.c ../doc/man.macros
          mkdir "$HOME/install dir"
          echo "USE_XVFB=$SET_DISPLAY" >> $GITHUB_ENV
      - name: Add X11 (if required)
        if: ${{ env.USE_XVFB == 'true' }}
        run: |
          brew install --cask xquartz
          sudo /opt/X11/libexec/privileged_startx || true
        working-directory: .
      - name: Build Tcl
        # Note that macOS is always a 64 bit platform
        run: |
          ./configure --enable-64bit $CFGOPT "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Tcl Configure"
            exit 1
          }
          make all || {
            echo "::error::Failure during Tcl Build"
            exit 1
          }
          make install || {
            echo "::error::Failure during Tcl Install"
            exit 1
          }
        working-directory: tcl/unix
        env:
          CFGOPT: --enable-symbols=${{ matrix.symbols }}
      - name: Configure (symbols=${{ matrix.symbols }} ${{matrix.options }})
        # Note that macOS is always a 64 bit platform
        run: |
          ./configure --enable-64bit $CFGOPT "--prefix=$HOME/install dir" --disable-xft || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
        env:
          CFGOPT: --enable-symbols=${{ matrix.symbols }} ${{matrix.options }}
      - name: Build
        run: |
          make binaries libraries tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          if [ $USE_XVFB == true ]; then
            function runXvfb {
              PATH=$PATH:/opt/X11/bin
              Xvfb $1 &
              XVFB_PID=$!
              echo Launched Xvfb $1 as process $XVFB_PID >&2
              trap "echo killing process $XVFB_PID... >&2; kill $XVFB_PID" 0
              export DISPLAY=$1
              sleep 2
            }
          else
            function runXvfb {
              echo Xvfb not used, this is a --enable-aqua build
            }
          fi
          ( runXvfb :0; make test-classic; exit $? ) | tee out-classic.txt || {
            echo "::error::Failure during Test (classic)"
            exit 1
          }
          ( runXvfb :0; make test-ttk; exit $? ) | tee out-ttk.txt || {
            echo "::error::Failure during Test (ttk)"
            exit 1
          }
          cat out-classic.txt | grep -q "Failed	0" || {
            echo "::error::Failure in classic test results"
            exit 1
          }
          cat out-ttk.txt | grep -q "Failed	0" || {
            echo "::error::Failure in ttk test results"
            exit 1
          }
        timeout-minutes: 20
      - name: Carry out trial installation
        run: |
          make install || {
            cat config.log
            echo "::error::Failure during Install"
            exit 1
          }
Added .github/workflows/win-build.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
name: Windows
on:
  push:
    branches:
    - "main"
    - "core-8-branch"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
env:
  ERROR_ON_FAILURES: 1
jobs:
  msvc:
    runs-on: windows-2022
    defaults:
      run:
        shell: powershell
        working-directory: tk/win
    # Using powershell means we need to explicitly stop on failure
    strategy:
      matrix:
        config:
          - ""
          - "OPTS=symbols"
          - "OPTS=static"
          - "OPTS=static,staticpkg"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 8.6
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Init MSVC
        uses: ilammy/msvc-dev-cmd@v1
      - name: Make Install Location
        working-directory: tcl
        run: |
          echo "TCLDIR=`pwd`" >> $GITHUB_ENV
          cd ..
          mkdir install
          cd install
          echo "INSTALLDIR=`pwd`" >> $GITHUB_ENV
      - name: Build Tcl (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc release install ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
        working-directory: tcl/win
      - name: Build Tk (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc all ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Build Test Harness (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc tktest ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Run Tk Tests (${{ matrix.config }})
        run: |
          nmake -f makefile.vc test-classic ${{ matrix.config }} | tee out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          nmake -f makefile.vc test-ttk ${{ matrix.config }} | tee out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        env:
          CI_BUILD_WITH_MSVC: 1
        shell: bash
        timeout-minutes: 10
      - name: Build Help (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc htmlhelp ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Install (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc install ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
  gcc:
    runs-on: windows-2019
    defaults:
      run:
        shell: msys2 {0}
        working-directory: win
    strategy:
      matrix:
        config:
          - ""
          - "--enable-symbols=mem"
          - "--enable-symbols=all"
          - "--disable-shared"
    steps:
      - name: Install MSYS2
        uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          install: git mingw-w64-x86_64-toolchain make
      - name: Checkout Tk
        uses: actions/checkout@v4
      - name: Checkout Tcl 8.6
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Prepare
        run: |
          touch tkStubInit.c
          touch "${HOME}/forWinDialog-5.12.7"
          mkdir "${HOME}/install_dir"
          echo "INSTALL_DIR=${HOME}/install_dir" >> $GITHUB_ENV
        working-directory: generic
      - name: Configure and Build Tcl (${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$INSTALL_DIR" || {
            cat config.log
            echo "::warning::Failure during Tcl Configure"
            exit 1
          }
          make all install  || {
            echo "::warning::Failure during Tcl Build"
            exit 1
          }
          echo "TCL_CONFIG_PATH=`pwd`" >> $GITHUB_ENV
        env:
          CFGOPT: --enable-64bit ${{ matrix.config }}
        working-directory: tcl/win
      - name: Configure Tk (${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$HOME/INSTALL_DIR" "--with-tcl=$TCL_CONFIG_PATH" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
        env:
          CFGOPT: --enable-64bit ${{ matrix.config }}
      - name: Build Tk
        run: |
          make all tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tk Tests
        run: |
          make test-classic | tee out-classic.txt
          make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 10
Changes to .gitignore.
12
13
14
15
16
17
18

19
20
21
22
23

24
25
26
27
28
29

30
31
32
33



34
35
36
37
38
39
40
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33


34
35
36
37
38
39
40
41
42
43







+





+





-
+


-
-
+
+
+







*.res
*.sl
*.so
.fslckout
Makefile
Tk-Info.plist
Wish-Info.plist
Credits.html
autom4te.cache
config.cache
config.log
config.status
config.status.lineno
doc/man.macros
html
manifest.uuid
_FOSSIL_
*/tkConfig.sh
*/wish*
*/tktest*
*/tktest
*/versions.vc
*/version.vc
*/libtcl.vfs
*/libtcl_*.zip
*/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
1
2

3
4
5
6
7
8
9
10


-
+







<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>tk8.7</name>
	<name>tk8.6</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.
710
711
712
713
714
715
716
717

718
719
720
721
722
723
724
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724







-
+







	* generic/tkObj.c (GetPixelsFromObjEx): [Bug 3431491]: Use a bit of
	type hackery to allow numbers to be interpreted as coordinates (most
	notably on a canvas) without reinterpreting via a string.

2011-10-27  Kevin B. Kenny  <kennykb@acm.org>

	* generic/tkInt.h:	[Bug 3410609]: Change the event mechanism
	* unix/tkUnixEvent.c:	for <Key> events to use the keysym
	* unix/tkUnixEvent.c:	for <KeyPress> events to use the keysym
	* unix/tkUnixKey.c:	returned by XLookupString in preference to
	the one that appears in the raw X event at any level. This change
	allows binding to ISO_Level3_Shift-ed characters, composed characters,
	and similar beasts. KeyRelease events still work as they did before,
	as does Tk with input methods disabled.

2011-10-13  Jan Nijtmans  <nijtmans@users.sf.net>
3199
3200
3201
3202
3203
3204
3205
3206

3207
3208
3209
3210
3211
3212
3213
3199
3200
3201
3202
3203
3204
3205

3206
3207
3208
3209
3210
3211
3212
3213







-
+







	* library/demos/mclist.tcl: Added support for arrow indicators to show
	which way a column is being sorted. Corrected determination of which
	fonts to use for measurements.

2009-03-25  Jan Nijtmans  <nijtmans@users.sf.net>

	* doc/wish.1:		Bring doc and demos in line with
	* library/demos/hello:	http://wiki.tcl.tk/812
	* library/demos/hello:	https://wiki.tcl-lang.org/page/exec+magic
	* library/demos/rmt
	* library/demos/square
	* library/demos/tcolor
	* library/demos/timer
	* library/demos/widget
	* win/tkWinMenu.c:	Eliminate a few compiler warnings on mingw
	* win/ttkWinXPTheme.c:	Spacing
5209
5210
5211
5212
5213
5214
5215
5216

5217
5218
5219
5220
5221
5222
5223
5209
5210
5211
5212
5213
5214
5215

5216
5217
5218
5219
5220
5221
5222
5223







-
+







2008-01-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/canvas.n, doc/listbox.n, doc/message.n: [Bug 1882495]: Fix
	erroneous listing of "standard" options.

2008-01-29  Joe English  <jenglish@users.sourceforge.net>

	* library/treeview.tcl: Fix bug in Shift-Button-1 binding (error
	* library/treeview.tcl: Fix bug in Shift-ButtonPress-1 binding (error
	if no current focus item; reported on c.l.t.)

2008-01-29  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

	* doc/ttk_*.n: [Bug 1876493]: Adjusted handling of the standard
	options part of the Ttk manual pages so that they are documented in
	the correct location.
Changes to ChangeLog.2002.
2234
2235
2236
2237
2238
2239
2240
2241

2242
2243
2244
2245
2246
2247
2248
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).
	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):
Changes to ChangeLog.2004.
807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
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.
	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
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]
	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.
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
23
24
25
26
27

28
29
30
31
32
33
34
1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29

30
31
32
33
34
35

36
37
38
39
40
41
42
43


-
+




+
+
+
+
+
+
+
+
+







-
+





-
+





-
+







# README:  Tk

This is the **Tk 8.7a4** source distribution.
This is the **Tk 8.6.16** source distribution.

You can get any source release of Tk from [our distribution
site](https://sourceforge.net/projects/tcl/files/Tcl/).

9.0 (production release, daily build)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/linux-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/linux-build.yml?query=branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/win-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/win-build.yml?query=branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/mac-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/mac-build.yml?query=branch%3Amain)
<br>
8.6 (this release, daily build)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/linux-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/linux-build.yml?query=branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/win-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/win-build.yml?query=branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/mac-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/mac-build.yml?query=branch%3Acore-8-6-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.7 Web page](https://www.tcl.tk/software/tcltk/8.7.html)
this release, see [the Tcl/Tk 8.6 Web page](https://www.tcl-lang.org/software/tcltk/8.6.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/).
take place at [core.tcl-lang.org](https://core.tcl-lang.org/).
Tcl/Tk release and mailing list services are [hosted by
SourceForge](https://sourceforge.net/projects/tcl/)
with the Tcl Developer Xchange hosted at
[www.tcl-lang.org](https://www.tcl-lang.org).

Tk is a freely available open source package.  You can do virtually
Tk is a freely available open-source package.  You can do virtually
anything you like with it, such as modifying it, redistributing it,
and selling it either in whole or in part.  See the file
`license.terms` for complete information.

## <a id="tcl">2.</a> See Tcl README.md

Please see the README.md file that comes with the associated Tcl release
Changes to changes.
3484
3485
3486
3487
3488
3489
3490
3491

3492
3493
3494
3495
3496
3497
3498
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
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)

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
7412
7413
7414
7415
7416
7417
7418























7419
7420
7421
7422
7423
7424
7425







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








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)
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


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
7761
7762
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
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
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
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
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
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
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
7945
7946
7947
7948
7949
7950
7951
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
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
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
8099
8100
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
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164

8165
8166
8167
8168

8169
8170
8171
8172

8173
8174
8175
8176

8177
8178
8179
8180

8181
8182
8183
8184

8185
8186
8187
8188
8189
8190

8191
8192
8193
8194

8195
8196
8197
8198
8199
8200
8201
8202
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
8235
8236

8237
8238
8239
8240
8241
8242

8243
8244
8245
8246
8247

8248
8249
8250
8251
8252
8253

8254
8255







+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+


+
-
+
+

+
-
+
+

+
-
+
+

+
-
+
+

+
-
+
+

+
+
+
-
+
+

+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
+
+
+

+
-
+
+
+

+
+
-
+
+
+

+
-
+
+
+

+
+
-
+
+
+

+
+
-
+
+
+

+
-
+
+
+

+
+
-
+
+

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

2019-11-25 (bug)[a95373] TkKeyEvent platform variations (werner)
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:

2019-11-26 (bug) workaround Win bug so test bind-34.3 passes (nijtmans)

2019-12-03 Aqua: white cursors in dark mode (culler)

2019-12-04 (bug)[749bd9] Aqua: systemControlAccentColor (bll,culler)

2019-12-14 (bug)[b3b56a] ttk respect -cursor option (vogel)

2019-12-14 (bug)[b094cb] Win: $tv -show grows widget width 1 pixel (vogel)

2019-12-14 (bug)[02a694] spinbox options used wrong db names (vogel)

2020-01-11 (bug)[2b8fa6] MouseWheel for ttk::scrollbar (oehlmann)

2020-01-18 (bug)[1771594] icursor and scrollregion, canvText-14.7 (vogel)

2020-01-18 (bug)[587937] tag list ops preserve list order (vogel)

2020-01-18 (bug)[2830360] lose invalid state at focus event, entry-10.1 (vogel)

2020-01-18 (bug)[077d49] string table options support null ok (vogel)

2020-01-18 (bug)[bf93d0] Aqua: unresponsive menubar (culler)

2020-01-31 (bug)[a196fb] restore support for unthreaded Tcl (porter,sebres)

2020-02-09 (bug)[90a4d7] fontconfig crash when no font installed (vogel)

2020-02-24 (bug) Aqua: incomplete floating window display (walzer)

2020-03-11 (bug)[fb2ec3] OSX 10.15+: full screen options (nicolas,walzer)

2020-03-12 (bug)[08e2f8] focus on unmapped windows, focus-7.1 (vogel)

2020-03-12 (bug)[2edd84] [$c postscript] result management (gavilan)

2020-03-22 (bug)[98662d] restore TK_MAC_DEBUG_DRAWING build (chavez)

2020-03-29 (bug)[655fe2] tearoff menu redraw artifacts (vogel)

2020-04-03 (bug)[efbedd] Aqua: compund button-like widget appearance (chavez)

2020-04-14 (bug)[87bade] Aqua: improved dealing with PressAndHold (culler)

2020-04-14 (bug)[376788] X: stop crash w/Noto Color Emoji font (nijtmans)

2020-04-15 (bug)[89354d] Aqua: text color w/o clipping (culler)

2020-04-15 (new) Aqua: assign Button 3 to the middle button (chavez)

2020-04-25 (bug)[3519111] treeview horizontal scroll, entry-2.1.1 (vogel)

2020-04-25 (bug)[141881] treeview vertical scroll, treeview-9.2 (vogel)

2020-05-01 (bug)[2712f4] X: crash angled text w/o Xft, canvText-20.2 (vogel)

2020-05-01 (bug)[cd8714] Win: long angled text (chavez)

2020-05-09 (bug)[88c9e0] treeview -selectmode none focus ring (gavilan)

2020-05-12 (new) Aqua: Rewrite of the Key event system (culler)

2020-05-12 (bug)[411359] Aqua: stop crashes/zombies related to TouchBar (culler)

2020-05-12 (new) Aqua: systemLinkColor (chavez)

2020-05-16 (bug)[40ada9] crash when active button is destroyed (chavez)

2020-05-28 (bug)[3c6660,601cea,4b50b7] Win10: ttk scale (nemethi,lanam)

2020-06-08 (bug)[2790615] Some callbacks not eval'd in global scope (nijtmans)

2020-06-25 Aqua: Update OSX version tests to support Big Sur (culler)

2020-06-27 (bug)[6920b2] dup in spinbox -values causes trouble (lanam)

2020-06-27 (bug)[5c51be] invalid mem read buffer in Tk_PhotoPut* (chavez)

2020-06-27 (bug)[16ef16] restore bind sequence support, bind-33.(16-21) (vogel)

2020-07-02 (bug)[2d2459] default style for combobox (bll)

2020-07-06 (bug)[40e4bf] double free, entry-19.21 (vogel)

2020-07-06 (bug)[e3888d] grab & warp, bind-36.1 (vogel)

2020-07-12 (bug)[2442314] fontchooser i18n (nijtmans)

2020-07-13 (bug)[7655f6] [*entry]: selected text drawing reform (chavez)

2020-07-14 (bug)[09abd7] workaround invalid key codes from Debian 10 (vogel)

2020-07-20 (bug)[cf3853] Aqua: improve bounds on non-Retina displays (chavez)

2020-08-01 Aqua: [winfo rgb] light and dark mode support (culler)

2020-08-15 (bug)[315104] Aqua: appearance change virtual events (culler)

2020-08-21 (bug)[291699] mouse binding for scrollbar grip (bll)

2020-09-08 (bug)[6c2425] buffer bounds violation (chavez)

2020-09-08 (bug)[2a6d63] OSX 10.6 crash (hellstrom,culler)

2020-09-08 (bug)[420feb] undefined behavior due to alignment (chavez,nijtmans)

2020-09-10 (bug)[ab1fea] Aqua init issues (culler)

2020-09-14 (bug)[71e18c] Aqua: crash in full screen toggle (culler)

2020-09-18 (bug)[4f4f03] Aqua: mouse drags across title bar (nab,culler)

2020-09-21 (bug)[d91e05] select/copy in disabled text (bll)

2020-09-27 (TIP #581) disfavor Master/Slave terminology (nijtmans)

2020-09-30 (bug)[59cba3] win: improve theme detection (bll,nijtmans)

2020-10-06 (bug)[175a6e] Aqua: support tiled windows (culler)

2020-10-07 (bug)[1fa8c3] Aqua: crash on resize during display (nab,culler)

2020-10-16 (bug)[c2483b] Aqua: consistent finalization (culler,nijtmans)

2020-11-06 (bug)[c9ebac] Aqua: use standard about dialog (culler)

2020-11-07 (bug)[4ebcc0] sticky fontchooser options (roseman,vogel)

2020-11-10 (bug)[f9fa92] Aqua: crash in color caching scheme (culler)

2020-11-20 (bug)[7185d2] Aqua: fixes to special menu support (culler)

2020-11-24 (bug)[4a40c6] Aqua: [wm manage] frame offset (chavez)

2020-12-04 (bug)[3ef77f] Aqua dark mode combobox focus ring (walzer,culler)

2020-12-15 (bug)[80e4c6] Aqua: progressbar animation (nab,culler)

2020-12-24 (bug)[6157a8] Aqua: file dialog -filetypes (davis,culler)

- Released 8.6.11, Dec 31, 2020 - https://core.tcl-lang.org/tk/ for details

2021-01-04 (bug)[19fb7a] Mac: [tk_messageBox] use proper icons (ericwb,culler)

2021-01-11 (bug)[7beaed] ttk::bindMouseWheel syntax error (nemethi)

2021-01-15 (new) support 4 new keycodes: CodeInput, SingleCandidate,
	MultipleCandidate, PreviousCandidate (nijtmans)

2021-01-18 (new) Portable keycodes: OE, oe, Ydiaeresis (nijtmans)

2021-01-27 (bug)[bdcab8] Mac crash on non-BMP menu label (nab,culler)

2021-02-07 (bug)[9e1312] <Enter> to parent after child destroyed (leunissen)

2021-02-10 (bug)[d3cd4c] more robust notebook processing (nemethi)

2021-02-25 (bug)[234ee4] crash in [clipboard get] invalid encoding (nijtmans)

2021-02-25 (bug)[be9cad] Poor trace housekeeping -> tkwait segfault (michael)

2021-03-02 (bug)[1626ed] Mac: crash with dead key as menu accelerator (culler)

2021-03-22 (bug)[9b6065] restore Tcl [update], see window-2.12 (leunissen)

2021-04-07 (bug)[58222c] Mac: entry and spinbox bg colors (chavez,culler)

2021-04-18 (bug)[34db75,ea876b] cursor motion in peer text (vogel)

2021-04-26 (bug)[c97464] memleak in TkpDrawAngledChars (nab,culler)

2021-04-29 Mac: explicit backing CALayer to fix rendering issues (culler)

2021-05-02 Mac: respect key repeat system setting (culler)

2021-05-10 (bug)[171ba7] crash when grab and focus are not coordinated (culler)

2021-05-24 crash due to failed transient record housekeeping (culler)

2021-05-25 (bug)[7bda98] Mac: <Double-1> bindings fire twice on app activation

2021-06-03 (bug)[4401d3] Mac: improved support of pixel formats (chavez,culler)

2021-06-03 (bug)[8ecc3e] Mac: window exposed by Mission Control (chavez,culler)

2021-06-04 (bug)[099109] segfault reusing a container toplevel (culler)

2021-06-22 (bug)[4efbfe] static package init order in wish (werner)

2021-09-21 (bug)[033886] Win: hang in font loading (e-paine,vogel)

2021-10-14 (bug)[8ebed3] multi-thread safety in Xft use (werner)

2021-10-22 (new)[TIP 608] New virtual event <<TkWorldChanged>> (griffin)

2021-10-27 (bug) file dialog compatibility with Mac OS 12 (culler)

2021-10-29 (bug) Mac: stop crash when non-Tk windows go full screen (werner)

2021-10-30 (bug)[6ea0b3] Mac: grab from menu makes dead window (culler)

- Released 8.6.12, Nov 5, 2021 - https://core.tcl-lang.org/tk/ for details

2021-11-09 (bug)[e699a7] Fix build on macOS < 10.12 (culler)

2021-11-10 (bug)[8aebca,ce5d98] Mac: fix minimize button details (culler)

2021-11-24 (bug)[18682c,733dae] Mac: Enter/Leave events for toplevels (culler)

2021-11-29 (bug)[4ac9d2] Mac: canvas screenshot with Img package position
	correction (chavez)

2021-11-30 (documentation cleanup) [bad305] improve wm protocol
	WM_DELETE_WINDOW documentation (culler)

2021-11-30 (new) Mac: new color index "SelectedMenuItemTextColor".

2021-12-01 (new)[TIP 599] Extended build information (nijtmans)

2021-12-04 (bug)[440c52] fix PPM/PGM read with graylevel > 255 (vogel)

2021-12-04 (bug)[5fb814] canvas redraw region for lines/polygones (vogel)

2021-12-04 (new)[631a0b] text widget: direct mouse events to insert mark, not
	current (vogel)

2021-12-06 (bug)[b164ef] fix mouse events for multiple toplevels (culler)

2021-12-07 (bug)[be8f5b] crash setting -type empty for a menu (vogel)

2021-12-10 (bug)[50fc02,50fc02,25894d,156e58] ImgPhoto pointer issues (chavez)

2021-12-20 (bug)[617861] -justify/-anchor defaults for ttk::label (nijtmans)

2021-12-20 (bug)[6be8b0] Mac: crash on drag and Cmd-w (culler)

2021-12-22 (bug)[a132b5] Mac: esc on combobox menu influences click reopening
	(culler)

2021-12-24 (bug)[915316] Mac: drag events not to initial widget (culler)

2021-12-27 (bug)[eb26d4] Mac: wrong beep when clicking outside a combobox
	(culler)

2021-12-30 (bug)[822450] Mac: crash on exit (culler)

2022-01-06 (bug)[b7d851] Mac: crash on tkdnd drop and window close (culler)

2022-01-09 (bug)[40bc81] embedding error test failure (vogel)

2022-01-16 (bug)[b1d115] No <Enter> event on new toplevel on current toplevel
	destruction (vogel)

2022-02-03 (bug)[3fefb3] crash in empty ttk::combobox when end index requested
	(vogel)

2022-02-07 (new)[247d80] Chinese message file (NewbieXvwu)

2022-02-07 (new) Support Windows ARM platform (nijtmans)

2022-02-11 (bug)[e331bc] NULL to memset in photo blank (chavez)

2022-02-12 (bug)[fc5073] Mac: crash on native file dialog and tooltip (walzer)

2022-02-17 (bug)[864b06] PNG photo image color numeric issue (chavez)

2022-02-24 (bug)[141a11] Mac: dialog box with global grab inresponsive on
	click in other toplevel (walzer)

2022-02-25 (bug)[f75190] tk_fontchooser: multiple font families, locale
	change, button activation (holger,vogel)

2022-02-25 (bug)[ce6b42] (in TCL bug tracker) ttk::spinbox increment event
	endless invokation (vogel)

2022-02-26 (bug)[c7052d] Win: middle mouse click blocks system clipbord
	(vogel)

2022-02-27 (bug)[292598,01acde,e02fc96,0c3dbe,ee49f3,d175bb] Mac: memory leaks
	(images, focus ring) (chavez)

2022-03-07 (bug)[2a6c62] Avoid invalid <<TreeviewSelect>> events
	(vogel,spjuth)

2022-03-16 (new)[f47920] Updates to Finnish message catalog (hippelainen)

2022-03-16 (bug)[424773] crash in test canvPs-5.1 (chavez,vogel)

2022-03-19 (bug)[5412c6] crash in test canvWind-2.1 (SVID,vogel,griffin)

2022-03-19 (bug)[54fe7a] crash in test textWind-18.3 (akuli,vogel)

2022-04-04 (bug)[29b5c2] error in tk_popup with separator entry selected
	(griffin)

2022-04-07 (bug)[415415] scale advances multiple steps on single click (vogel)

2022-04-10 (bug)[dc4c55] tk_popup entry index (mcdonald)

2022-04-15 (bug)[c0bf1b] XVirtualEvent buffer overflows (chavez)

2022-04-19 (new)[8dd3d5] Mac : use Fn + e to access Emoji (nijtmans)

2022-05-11 (bug)[88cfdc] Mac: dialog memory, avoid use after free (chavez)

2022-04-21 (new)[bf0f48] Mac: Optimization for compilation is now -O2
	(nijtmans)

2022-05-08 (bug)[eedd79] potential crashes in option parsing when sizeof(enum)
	not equal to int (nijtmans)

2022-05-08 (bug)[0ce975] panedwindow calls memcpy with NULL pointer (chavez)

2022-05-22 (bug)[bee96b] Win: cursor warp, [tk busy] (mcdonald)

2022-06-07 (bug) GIF with multiple images may reuse transparent color (oehhar)

2022-06-12 (bug)[e4a051] Mac: map embedded window immediately (vogel)

2022-06-15 (bug)[b18434] cygwin path compiling issues (fassel)

2022-06-27 [aefdb8,be29f7] Updates to Russian message catalog (pylypenko)

2022-07-04 Updates to Esperanto message catalog (ender)

2022-07-19 (bug)[91ca77] Mac: map event handling (rosenburger,culler,landers)

2022-07-20 (bug)[40bc81,17f44d,150174,61e0bb] embedding error test failures
	(vogel)

2022-07-25 (bug)[a3b03f] Linux, Windows: improve (ttk) menubutton menu
	position (danckaert,vogel)

2022-07-29 Update keysym tables to latest X11R6 (nijtmans)

2022-08-22 [f6e4d4] consistent cross-platform polygon fill (akuli,chavez)

2022-09-04 (bug)[bc6020] test treeview-bc602049ab (bende,spjuth)

2022-09-08 (bug)[e17b6f] Mac: crash in test unixW-50.4 (chavez)

2022-09-20 [33de84] Mac: handle Apple deprecation of OSTypes (culler)

2022-09-20 (bug)[412b80] Mac menu: arrow key and menu selection (nab,culler)

2022-09-22 (bug)[1a46d8,1fa325] Mac: memleak, crash safety in color (chavez)

2022-10-17 [d93c81] Workaround faulty compiler optimization in VS 2022 (vogel)

2022-10-26 (bug)[435739] crash in test bind-37.1 (csok,vogel)

2022-10-28 (bug)[5e4e44] ttk::panedwindow drag robust wrt orientation variants
	(xolodho,vogel)

- Released 8.6.13, Nov 22, 2022 - https://core.tcl-lang.org/tk/ for details

2022-12-12 Windows binaries licence metadata changed to  University of
        California to match licence (nadkarni)

2022-12-12 (bug)[6ee162] crash in [ttk::style configure] (vogel)

2022-12-14 Permit [tk scaling] to return scale factor in safe interp (nijtmans)

2023-01-05 Correct rounding of [nsFont pointSize] (nijtmans)

2023-01-08 (bug)[cee095] X error handler management in Tk_MeasureChars (kechel)

2023-01-18 macOS 13 SDK deprecates sprintf() (vogel)

2023-02-12 (bug)[170551] crash in [tk busy forget]

2023-02-27 (bug)[6cd476] crash using [tk busy hold] (vogel)

2023-03-04 (bug)[93fe36] Fix <<MenuSelect>> with -tearoff (mcdonald)

2023-03-30 (bug)[15c685] menu clones, tests menu-20.1[2-6] (bron)

2023-04-10 (bug)[f4d9d7] canvas items ignored -disabledwidth (chavez,vogel)

2023-04-30 (bug)[a9cf21] Text selection omits first character (moosems)

2023-05-03 (bug)[310c74] No theme change attempts after Tk finalize (chavez)

2023-05-13 (bug)[3414695] Dialogs robust against parent destruction (vogel)

2023-05-23 (bug)[ab9581] Guard against use-after-free crashes (chavez)

2023-05-23 (bug)[f40d9d] Aqua: FourCC bitmaps (chavez)

2023-05-25 (bug)[7447ed] [tk_chooseColor] handle grab fail (leunissen)

2023-05-31 (bug)[4666f2] Protect aganst NULL windows (nab,vogel)

2023-06-06 (bug)[a418aa] bogus @x,y menu entry indices, menu-22.[6-9] (vogel)

2023-06-11 (bug)[578441] memleak in TkScrollWindow (chavez)

2023-06-13 (bug)[228476] link wish to correct libtk (root)

2023-07-09 (bug)[a526d4] Aqua: memleak in TkpOpenDisplay (chavez)

2023-07-10 (bug)[fa4694,0502c1] Aqua: memleaks in TkpConfigureMenuEntry (chavez)

2023-07-17 (bug)[f9eddb] region clip & copy better OS implementations (chavez)

2023-07-18 (bug)[2cb602] Aqua: memleak in TkCreateRegion (chavez)

2023-07-19 (bug)[edb769] Aqua: memleak in XGetImage (chavez)

2023-07-19 (bug)[c35c34] memleak in Initialize (chavez)

2023-07-20 (bug)[deca94] memleak in TkpMakeMenuWindow (chavez)

2023-07-23 (bug)[f24725] crash using Aqua pre-defined bitmap names (chavez)

2023-07-24 (feature) better solve Y2038 on most systems (chavez,nijtmans)

2023-07-26 (bug)[ed9b28] Aqua: memleak in GetWidgetDemoPath (chavez)

2023-08-02 (bug)[2a3222] navigation exposed clues about masked entry

2023-08-04 Update [trace] subcommands for Tcl 9 compat

2023-08-29 (bug)[e42eef] memory issues interfacing with XIM (goodward)

2023-08-30 (bug)[ef5d3e] Aqua: crash after first toplevel destroyed (chavez)

2023-09-01 (bug)[6cc800] Harmonize number parsing with Tcl (nijtmans)
        *** POTENTIAL INCOMPATIBILITY ***

2023-09-03 (bug)[4468ed] Iconlist no fg text color from options db (chavez)
        *** POTENTIAL INCOMPATIBILITY ***

2023-09-04 (bug)[d2396a] error reporting from [send -option] (emanuele,nijtmans)

2023-10-11 (bug)[9675dd] wrong free() call from Tk_ConfigureValue (nijtmans)

2023-10 (bug) Many revisions to satisfy -fsanitize=function (chavez)
	[d96974,04d3e5,84fe25,bb8041]

2023-10-16 (bug)[22eefb] unixWm-45.[24] (vogel)

2023-10-18 (bug)[10b38a] Silence macOS 14 warning about secure restorable state

2023-10-28 (bug)[198376] move notebook tabs to position s (rozenberg,vogel)

2023-11-06 (bug)[499f8e] eliminate undefined realloc() calls (chavez)

2023-11-07 (bug)[09a11f] crash menu-40.[12] (chavez,culler)

2023-11-13 (bug)[eedd2e] ttk::notebook looks bad when tabs are positioned on
	edges other than the top (nemethi,werner)

2023-11-15 (bug)[61550f] font-44.1 with Xft (vogel)

2023-11-22 (bug)[22a4ad] Aqua: CoreGraphics manages memory for pixmaps (chavez)

2023-11-28 (bug)[900f23] PNG encoder missed 0xFF entry (obermeier)

2023-12-03 Aqua: Update handling of Apple FourCC creator codes (chavez)

2017-11-25 [TIP 161] $menu -tearoff default changed to false (roseman,vogel)
2023-12-03 (bug)[fe9423] Aqua: XPutImage() swap red and blue (chavez)
        *** POTENTIAL INCOMPATIBILITY ***

2023-12-09 (bug)[1d8b71] X: Photo color drawing for 32-bit visuals (warnholz)
2017-12-07 [TIP 487] End support for pre-XP Windows (nijtmans)

2023-12-12 Update to latest X11 headers

2023-12-22 (bug)[9c5742] Fix handling of abbreviated -relief args (nijtmans)
2018-03-04 [TIP 489] New subcommand [$canvas image] (pitcher,vogel)

2024-01-03 (bug)[52df66] nonXft: [font measure] results inconsistent (vogel)

2024-01-05 (bug)[a9e637] treeview display partial final line (bron)
2018-05-13 [TIP 496] New options -placeholder* for entries (zaumseil,vogel)

2024-01-09 (bug)[b7abf0] treeview destruction from O(N^2) to O(N) (emiliano)

2024-01-12 (bug)[737abf] text image insertion from O(N^2) to O(N)
2018-09-23 [TIP 517] New option -activerelief for menus (vogel)

2024-01-27 (bug)[8da7af] font caching performance issues (thraen,vogel)

2024-02-08 (bug)[57b821] see test textIndex-22.16 (vogel)
2018-11-03 [TIP 512] Deprecate stub for Tk_MainEx() (nijtmans)

- Released 8.6.14, Feb 28, 2024 - https://core.tcl-lang.org/tk/ for details

2024-03-15 (bug)[47d4f2] Invoke binding scripts for events with detail field
	NotifyInferior (leunissen, vogel)
	*** POTENTIAL INCOMPATIBILITY ***
2018-11-06 [TIP 415] New option -height for [$canvas create arc] (geard)

2024-03-19 (bug) [fdc0ed] Fix segfault on [focus -force] with xvfb (vogel)

2024-04-21 (bug) [ab839e] Fix [text undo] clearingdata
2018-11-06 [TIP 518] New event <<NoMangedChild>> (oehlmann)

2024-05-01 (change) [e30699] Fix appearence of arrows in ttk widgets
	(nemethi)

2024-05-03 (change) Add keycodes ISO_Group_Shift and dead_hamza (nijtmans)

2024-05-10 (change) Improve look of the classic theme (gavilan)

2024-05-11 (change) Improved focus ring for ttk (nemethi)

2024-05-13 (bug) [treeview identify] now point aware (vogel)

2024-05-29 (bug) Fix default font detection for high DPI (vogel,nemethi)

2024-06-02 (bug) Fix [ttk::combobox] covering down arrow (vogel,gavilan)

2024-06-09 (bug)  [a0241c] Fix performance of image copy (vogel)

2024-06-11 (bug) [157652] Fix image read with -from option for gif/png
	(vogel)
2019-04-14 [TIP 164] New subcommand [$canvas rotate] (fellows)

2024-06-18 (bug) [865af0] Throw error message on corrupt gif file
	(obermeier)

2024-07-06 (bug) [51ece3] Fix crash on [canvas dchars] (vogel)
2019-04-14 [TIP 507] New photo image format 'svg' (zaumseil)

2024-07-22 (bug)[2d3a81] fix segfault on menubutton destroy (MS-Win only)
	(oehlmann)

2024-07-31 (bug) [0d4879,089da4,f569b9] Improve focus ring for ttk widgets
	(nemethi)
2019-04-14 [TIP 483] Record more configuration items (cassoff)

2024-08-28 (bug) [d82fa2] [ttk::treview] painting/clipping/scrolling of last
	item (bron,nemethi,werner)

- Released 8.6.15, Sep 13, 2024 - https://core.tcl-lang.org/tk/ for details
2019-04-14 [TIP 482] Record configured directory for demos (cassoff)

2024-09-19 (bug) [18e984] Assignment of invalid symbolic constant
	 NotifyNormal (vogel)

2024-09-20 (bug) [398109] Segmentation fault with bogus resource value
	(X11) (emiliano)
2019-05-25 [TIP 262] New frame options -backgroundimage, -tile (fellows)

2024-09-21 [ttk] Improved the appearance of the Treeitem.indicator element
	(nemethi)

2024-09-27 (bug) [265d4e] macOS Sequoia: warning: 'setShowsResizeIndicator:'
	is deprecated (vogel)
2019-06-15 [TIP 528] Deprecate Tk_Offset() (nijtmans)

2024-10-09 (bug) [eb3328] [grid] and [pack] with half-dead argument can cause
	hangup or even crash (vogel)

2024-10-11 (bug) [f52986] SIGABRT from Tk_DeleteErrorHandler() (vogel)
2019-08-19 [TIP 545] Revised options for photo image format 'svg' (oehlmann)

2024-11-13 (bug) [36e379] [macOS Ventura] Workaround for X11 build with
	XQuartz: crash in XLoadQueryFont (vogel)

2024-11-25 (bug) [bcbf4c] Tk intialization overwrites thread specific data
	(emiliano)
--- Released 8.7a3, November 25, 2019 --- http://core.tcl.tk/tk/ for details

- Released 8.6.16, Dec 11, 2024 - https://core.tcl-lang.org/tk/ for details
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * 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 strtol/strtoul).
 *
 * 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

extern void		abort(void);
extern double		atof(const char *string);
extern int		atoi(const char *string);
extern long		atol(const char *string);
extern void *		calloc(unsigned long numElements, unsigned long size);
extern void		exit(int status);
extern void		free(void *blockPtr);
extern char *		getenv(const char *name);
extern void *		malloc(unsigned long numBytes);
extern void		qsort(void *base, unsigned long n, unsigned long size, int (*compar)(
			    const void *element1, const void *element2));
extern void *		realloc(void *ptr, unsigned long numBytes);
extern char *		realpath(const char *path, char *resolved_path);
extern int		mkstemps(char *templ, int suffixlen);
extern int		mkstemp(char *templ);
extern char *		mkdtemp(char *templ);
extern long		strtol(const char *string, char **endPtr, int base);
extern unsigned long	strtoul(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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * 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 NULL
#   define NULL    0
#endif

/*
 * Strict POSIX stuff goes here. Extensions go down below, in the ifndef
 * _POSIX_SOURCE section.
 */

extern void		_exit(int status);
extern int		access(const char *path, int mode);
extern int		chdir(const char *path);
extern int		chown(const char *path, uid_t owner, gid_t group);
extern int		close(int fd);
extern int		dup(int oldfd);
extern int		dup2(int oldfd, int newfd);
extern int		execl(const char *path, ...);
extern int		execle(const char *path, ...);
extern int		execlp(const char *file, ...);
extern int		execv(const char *path, char *const argv[]);
extern int		execve(const char *path, char *const argv[], char *const *envp);
extern int		execvp(const char *file, char *const argv[]);
extern pid_t		fork(void);
extern char *		getcwd(char *buf, size_t size);
extern gid_t		getegid(void);
extern uid_t		geteuid(void);
extern gid_t		getgid(void);
extern int		getgroups(int bufSize, int *buffer);
extern pid_t		getpid(void);
extern uid_t		getuid(void);
extern int		isatty(int fd);
extern long		lseek(int fd, long offset, int whence);
extern int		pipe(int *fildes);
extern int		read(int fd, char *buf, size_t size);
extern int		setgid(gid_t group);
extern int		setuid(uid_t user);
extern unsigned		sleep(unsigned seconds);
extern char *		ttyname(int fd);
extern int		unlink(const char *path);
extern int		write(int fd, const char *buf, size_t size);

#ifndef	_POSIX_SOURCE
extern char *		crypt(const char *, const char *);
extern int		fchown(int fd, uid_t owner, gid_t group);
extern int		flock(int fd, int operation);
extern int		ftruncate(int fd, unsigned long length);
extern int		ioctl(int fd, int request, ...);
extern int		readlink(const char *path, char *buf, int bufsize);
extern int		setegid(gid_t group);
extern int		seteuid(uid_t user);
extern int		setreuid(int ruid, int euid);
extern int		symlink(const char *, const char *);
extern int		ttyslot(void);
extern int		truncate(const char *path, unsigned long length);
extern int		vfork(void);
#endif /* _POSIX_SOURCE */

#endif /* _UNISTD */
Changes to doc/3DBorder.3.
9
10
11
12
13
14
15
16

17
18

19
20
21

22
23
24

25
26
27

28
29
30

31
32
33

34
35
36

37
38
39

40
41
42

43
44
45

46
47
48

49
50
51

52
53
54

55
56

57
58


59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
9
10
11
12
13
14
15

16
17

18
19
20

21
22
23

24
25


26
27


28
29


30
31


32
33


34
35


36
37


38
39
40

41
42
43

44
45
46

47
48

49
50

51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71







-
+

-
+


-
+


-
+

-
-
+

-
-
+

-
-
+

-
-
+

-
-
+

-
-
+

-
-
+


-
+


-
+


-
+

-
+

-
+
+











-
+







.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
\fB#include <tk.h>\fR
.sp

Tk_3DBorder
\fBTk_Alloc3DBorderFromObj(\fIinterp, tkwin, objPtr\fB)\fR
\fBTk_Alloc3DBorderFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
Tk_3DBorder
\fBTk_Get3DBorder(\fIinterp, tkwin, colorName\fB)\fR
\fBTk_Get3DBorder\fR(\fIinterp, tkwin, colorName\fR)
.sp
Tk_3DBorder
\fBTk_Get3DBorderFromObj(\fItkwin, objPtr\fB)\fR
\fBTk_Get3DBorderFromObj\fR(\fItkwin, objPtr\fR)
.sp
void
\fBTk_Draw3DRectangle(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fB)\fR
\fBTk_Draw3DRectangle\fR(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fR)
.sp
void
\fBTk_Fill3DRectangle(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fB)\fR
\fBTk_Fill3DRectangle\fR(\fItkwin, drawable, border, x, y, width, height, borderWidth, relief\fR)
.sp
void
\fBTk_Draw3DPolygon(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fB)\fR
\fBTk_Draw3DPolygon\fR(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fR)
.sp
void
\fBTk_Fill3DPolygon(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fB)\fR
\fBTk_Fill3DPolygon\fR(\fItkwin, drawable, border, pointPtr, numPoints, polyBorderWidth, leftRelief\fR)
.sp
void
\fBTk_3DVerticalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftBevel, relief\fB)\fR
\fBTk_3DVerticalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftBevel, relief\fR)
.sp
void
\fBTk_3DHorizontalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief\fB)\fR
\fBTk_3DHorizontalBevel\fR(\fItkwin, drawable, border, x, y, width, height, leftIn, rightIn, topBevel, relief\fR)
.sp
void
\fBTk_SetBackgroundFromBorder(\fItkwin, border\fB)\fR
\fBTk_SetBackgroundFromBorder\fR(\fItkwin, border\fR)
.sp
const char *
\fBTk_NameOf3DBorder(\fIborder\fB)\fR
\fBTk_NameOf3DBorder\fR(\fIborder\fR)
.sp
XColor *
\fBTk_3DBorderColor(\fIborder\fB)\fR
\fBTk_3DBorderColor\fR(\fIborder\fR)
.sp
GC *
\fBTk_3DBorderGC(\fItkwin, border, which\fB)\fR
\fBTk_3DBorderGC\fR(\fItkwin, border, which\fR)
.sp
\fBTk_Free3DBorderFromObj(\fItkwin, objPtr\fB)\fR
\fBTk_Free3DBorderFromObj\fR(\fItkwin, objPtr\fR)
.sp
\fBTk_Free3DBorder(\fIborder\fB)\fR
\fBTk_Free3DBorder\fR(\fIborder\fR)
.fi
.SH ARGUMENTS
.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
.AP "const 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
188
189
190
191
192
193
194
195
196


197
198
199
200
201
202
203
182
183
184
185
186
187
188


189
190
191
192
193
194
195
196
197







-
-
+
+







\fIwidth\fR and \fIheight\fR are the dimensions of the window), and
\fIborderWidth\fR specifies the number of pixels actually
occupied by the border.  The \fIrelief\fR argument indicates
which of several three-dimensional effects is desired:
\fBTK_RELIEF_RAISED\fR means that the interior of the rectangle should
appear raised relative to the exterior of the rectangle, and
\fBTK_RELIEF_SUNKEN\fR means that the interior should appear depressed.
\fBTK_RELIEF_GROOVE\fR and \fBTK_RELIEF_RIDGE\fR mean that there should appear to be
a groove or ridge around the exterior of the rectangle.
\fBTK_RELIEF_GROOVE\fR and \fBTK_RELIEF_RIDGE\fR mean that there should
appear to be a groove or ridge around the exterior of the rectangle.
.PP
\fBTk_Fill3DRectangle\fR is somewhat like \fBTk_Draw3DRectangle\fR except
that it first fills the rectangular area with the background color
(one corresponding
to the color used to create \fIborder\fR).  Then it calls
\fBTk_Draw3DRectangle\fR to draw a border just inside the outer edge of
the rectangular area.  The argument \fIrelief\fR indicates the desired
287
288
289
290
291
292
293
294


281
282
283
284
285
286
287

288
289







-
+
+
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
3D, background, border, color, depressed, illumination, value, polygon,
raised, shadow, three-dimensional effect
Changes to doc/AddOption.3.
29
30
31
32
33
34
35
36
37
38



39
40

41
42

43
44
45
46

47
48
49
50
29
30
31
32
33
34
35



36
37
38
39

40
41

42
43
44
45

46
47
48
49
50







-
-
-
+
+
+

-
+

-
+



-
+




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;
this value will be returned in calls to \fBTk_GetOption\fR.
\fIPriority\fR specifies the priority of the value; when options are
queried using \fBTk_GetOption\fR, the value with the highest priority
is returned.  \fIPriority\fR must be between 0 and \fBTK_MAX_PRIO\fR.  Some
common priority values are:
.IP 20
is returned.  \fIPriority\fR must be between 0 and \fBTK_MAX_PRIO\fR (100).
Some common priority values are:
.IP \fBTK_WIDGET_DEFAULT_PRIO\fR (20)
Used for default values hard-coded into widgets.
.IP 40
.IP \fBTK_STARTUP_FILE_PRIO\fR (40)
Used for options specified in application-specific startup files.
.IP 60
.IP \fBTK_USER_DEFAULT_PRIO\fR (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
.IP \fBTK_INTERACTIVE_PRIO\fR (80)
Used for options specified interactively after the application starts
running.
.SH KEYWORDS
class, name, option, add
Changes to doc/ConfigWidg.3.
11
12
13
14
15
16
17
18

19
20
21

22
23
24

25
26


27
28
29
30
31
32
33
11
12
13
14
15
16
17

18
19
20

21
22
23

24
25

26
27
28
29
30
31
32
33
34







-
+


-
+


-
+

-
+
+







.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
\fBTk_ConfigureWidget\fR(\fIinterp, tkwin, specs, argc, argv, widgRec, flags\fR)
.sp
int
\fBTk_ConfigureInfo(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
\fBTk_ConfigureInfo\fR(\fIinterp, tkwin, specs, widgRec, argvName, flags\fR)
.sp
int
\fBTk_ConfigureValue(\fIinterp, tkwin, specs, widgRec, argvName, flags\fB)\fR
\fBTk_ConfigureValue\fR(\fIinterp, tkwin, specs, widgRec, argvName, flags\fR)
.sp
\fBTk_FreeOptions(\fIspecs, widgRec, display, flags\fB)\fR
\fBTk_FreeOptions\fR(\fIspecs, widgRec, display, flags\fR)
.fi
.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
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74







-
-
+
+







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
Note that \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
of code that must be written in individual widget managers to
handle configuration information.
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118







-
+







.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 \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
157
158
159
160
161
162
163
164
165



166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250

251
252
253
254

255
256
257
258
259
260

261
262
263
264
265
266

267
268
269
270
271

272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299

300
301
302
303
304
305
306

307
308
309
310
311
312

313
314
315
316
317
318

319
320
321
322
323
324
325
326


327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348

349
350
351
352
353
354
355

356
357
358
359
360
361
362
158
159
160
161
162
163
164


165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344


345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385







-
-
+
+
+








+














+






+










+



















+










+








+










+




+






+






+





+










+










+








+







+






+






+






-
-
+
+








+














+







+







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
\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.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeCursor\fR.
.TP
\fBTK_CONFIG_ANCHOR\fR
.
The value must be an ASCII string identifying an anchor point in one of the ways
accepted by \fBTk_GetAnchor\fR.
The string is converted to a \fBTk_Anchor\fR by calling
\fBTk_GetAnchor\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_BITMAP\fR
.
The value must be an ASCII string identifying a bitmap in a form
suitable for passing to \fBTk_GetBitmap\fR.  The value is converted
to a \fBPixmap\fR by calling \fBTk_GetBitmap\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target is set to \fBNone\fR.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeBitmap\fR.
.TP
\fBTK_CONFIG_BOOLEAN\fR
.
The value must be an ASCII string specifying a boolean value.  Any
of the values
.QW true ,
.QW yes ,
.QW on ,
or
.QW 1 ,
or an abbreviation of one of these values, means true;
any of the values
.QW false ,
.QW no ,
.QW off ,
or
.QW 0 ,
or an abbreviation of one of these values, means false.
The target is expected to be an integer;  for true values it will
be set to 1 and for false values it will be set to 0.
.TP
\fBTK_CONFIG_BORDER\fR
.
The value must be an ASCII string identifying a border color in a form
suitable for passing to \fBTk_Get3DBorder\fR.  The value is converted
to a (\fBTk_3DBorder *\fR) by calling \fBTk_Get3DBorder\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_Free3DBorder\fR.
.TP
\fBTK_CONFIG_CAP_STYLE\fR
.
The value must be
an ASCII string identifying a cap style in one of the ways
accepted by \fBTk_GetCapStyle\fR.
The string is converted to an integer value corresponding
to the cap style by calling
\fBTk_GetCapStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_COLOR\fR
.
The value must be an ASCII string identifying a color in a form
suitable for passing to \fBTk_GetColor\fR.  The value is converted
to an (\fBXColor *\fR) by calling \fBTk_GetColor\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to \fBNone\fR.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeColor\fR.
.TP
\fBTK_CONFIG_CURSOR\fR
.
This option is identical to \fBTK_CONFIG_ACTIVE_CURSOR\fR except
that the new cursor is not made the active one for \fItkwin\fR.
.TP
\fBTK_CONFIG_CUSTOM\fR
.
This option allows applications to define new option types.
The \fIcustomPtr\fR field of the entry points to a structure
defining the new option type.
See the section \fBCUSTOM OPTION TYPES\fR below for details.
.TP
\fBTK_CONFIG_DOUBLE\fR
.
The value must be an ASCII floating-point number in
the format accepted by \fBstrtol\fR.  The string is converted
to a \fBdouble\fR value, and the value is stored in the
target.
.TP
\fBTK_CONFIG_END\fR
.
Marks the end of the table.  The last entry in \fIspecs\fR
must have this type;  all of its other fields are ignored and it
will never match any arguments.
.TP
\fBTK_CONFIG_FONT\fR
.
The value must be an ASCII string identifying a font in a form
suitable for passing to \fBTk_GetFont\fR.  The value is converted
to a \fBTk_Font\fR by calling \fBTk_GetFont\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeFont\fR.
.TP
\fBTK_CONFIG_INT\fR
.
The value must be an ASCII integer string
in the format accepted by \fBstrtol\fR (e.g.
.QW 0
and
.QW 0x
prefixes may be used to specify octal or hexadecimal
numbers, respectively).  The string is converted to an integer
value and the integer is stored in the target.
.TP
\fBTK_CONFIG_JOIN_STYLE\fR
.
The value must be
an ASCII string identifying a join style in one of the ways
accepted by \fBTk_GetJoinStyle\fR.
The string is converted to an integer value corresponding
to the join style by calling
\fBTk_GetJoinStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_JUSTIFY\fR
.
The value must be
an ASCII string identifying a justification method in one of the
ways accepted by \fBTk_GetJustify\fR.
The string is converted to a \fBTk_Justify\fR by calling
\fBTk_GetJustify\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_MM\fR
.
The value must specify a screen distance in one of the forms acceptable
to \fBTk_GetScreenMM\fR.
The string is converted to double-precision floating-point distance
in millimeters and the value is stored in the target.
.TP
\fBTK_CONFIG_PIXELS\fR
.
The value must specify screen units in one of the forms acceptable
to \fBTk_GetPixels\fR.
The string is converted to an integer distance in pixels and the
value is stored in the target.
.TP
\fBTK_CONFIG_RELIEF\fR
.
The value must be an ASCII string identifying a relief in a form
suitable for passing to \fBTk_GetRelief\fR.  The value is converted
to an integer relief value by calling \fBTk_GetRelief\fR and the result
is stored in the target.
.TP
\fBTK_CONFIG_STRING\fR
A copy
of the value is made by allocating memory space with
.
A copy of the value is made by allocating memory space with
\fBTcl_Alloc\fR and copying the value into the dynamically-allocated
space.  A pointer to the new string is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target was not NULL, then it is
freed by passing it to \fBTcl_Free\fR.
.TP
\fBTK_CONFIG_SYNONYM\fR
.
This \fItype\fR value identifies special entries in \fIspecs\fR that
are synonyms for other entries.  If an \fIargv\fR value matches the
\fIargvName\fR of a \fBTK_CONFIG_SYNONYM\fR entry, the entry is not used
directly. Instead, \fBTk_ConfigureWidget\fR searches \fIspecs\fR
for another entry whose \fIargvName\fR is the same as the \fIdbName\fR
field in the \fBTK_CONFIG_SYNONYM\fR entry;  this new entry is used just
as if its \fIargvName\fR had matched the \fIargv\fR value.  The
synonym mechanism allows multiple \fIargv\fR values to be used for
a single configuration option, such as
.QW \-background
and
.QW \-bg .
.TP
\fBTK_CONFIG_UID\fR
.
The value is translated to a \fBTk_Uid\fR
(by passing it to \fBTk_GetUid\fR).  The resulting value
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
377
378
379
380
381
382
383
384


385
386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402

403
404
405
406
407

408
409
410
411
412
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
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 \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.
.PP
First, if the \fIflags\fR argument to \fBTk_ConfigureWidget\fR has
the \fBTK_CONFIG_ARGV_ONLY\fR bit set (i.e., \fIflags\fR | \fBTK_CONFIG_ARGV_ONLY\fR != 0),
the \fBTK_CONFIG_ARGV_ONLY\fR bit set
(i.e., \fIflags\fR | \fBTK_CONFIG_ARGV_ONLY\fR != 0),
then the option database and
\fIdefValue\fR fields are not used.  In this case, if an entry in
\fIspecs\fR does not match a field in \fIargv\fR then nothing happens:
the corresponding target is not modified.  This feature is useful
when the goal is to modify certain configuration options while
leaving others in their current state, such as when a \fBconfigure\fR
widget command is being processed.
.PP
Second, the \fIspecFlags\fR field of an entry in \fIspecs\fR may be used
to control the processing of that entry.  Each \fIspecFlags\fR
field may consists of an OR-ed combination of the following values:
.TP
\fBTK_CONFIG_COLOR_ONLY\fR
.
If this bit is set then the entry will only be considered if the
display for \fItkwin\fR has more than one bit plane.  If the display
is monochromatic then this \fIspecs\fR entry will be ignored.
.TP
\fBTK_CONFIG_MONO_ONLY\fR
.
If this bit is set then the entry will only be considered if the
display for \fItkwin\fR has exactly one bit plane.  If the display
is not monochromatic then this \fIspecs\fR entry will be ignored.
.TP
\fBTK_CONFIG_NULL_OK\fR
.
This bit is only relevant for some types of entries (see the
descriptions of the various entry types above).
If this bit is set, it indicates that an empty string value
for the field is acceptable and if it occurs then the
target should be set to NULL or \fBNone\fR, depending
on the type of the target.
This flag is typically used to allow a
feature to be turned off entirely, e.g. set a cursor value to
\fBNone\fR so that a window simply inherits its parent's cursor.
If this bit is not set then empty strings are processed as strings,
which generally results in an error.
.TP
\fBTK_CONFIG_DONT_SET_DEFAULT\fR
.
If this bit is one, it means that the \fIdefValue\fR field of the
entry should only be used for returning the default value in
\fBTk_ConfigureInfo\fR.
In calls to \fBTk_ConfigureWidget\fR no default will be supplied
for entries with this flag set;  it is assumed that the
caller has already supplied a default value in the target location.
This flag provides a performance optimization where it is expensive
464
465
466
467
468
469
470







471
472
473
474
475
476
477
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512







+
+
+
+
+
+
+







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
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588







-
+







    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,
        const 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,
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
1
2
3
4
5
6
7
8
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) 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
Tk_CreateImageType, Tk_GetImageMasterData, 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_GetImageMasterData\fR(\fIinterp, name, typePtrPtr\fR)
.sp
.VS "TIP 581"
ClientData
\fBTk_GetImageModelData\fR(\fIinterp, name, typePtrPtr\fR)
.VE "TIP 581"
.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
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128







-
+







.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,
        Tk_ImageMaster \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
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243




244
245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262




263
264
265
266
267
268
269
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282







-
+










+
+
+
+











-
+







+
+
+
+







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
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 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.
.PP
.VS "TIP 581"
\fBTk_GetImageModelData\fR is synonym for \fBTk_GetImageMasterData\fR
.VE "TIP 581"
.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,
        Tk_ImageMaster \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
.VS "TIP 581"
\fITk_ImageModel\fR is synonym for \fITk_ImageMaster\fR
.VE "TIP 581"
.PP
When the \fBUSE_OLD_IMAGE\fR legacy support is enabled, you may
see the routine \fBTk_InitImageArgs\fR in use.  This was a migration
tool used to create stub-enabled extensions that could be loaded
into interps containing all versions of Tk 8.1 and later.  Tk 8.5 no longer
provides this routine, but uses a macro to convert any attempted
calls of this routine into an empty comment.  Any stub-enabled
Changes to doc/CrtItemType.3.
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85



86
87
88
89
90
91
92







-
+


















-
-
-







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;
    int \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
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
545
546
547
548
549
550
551








































552
553
554
555
556
557
558







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







.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
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
1
2
3
4
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 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
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)
.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
67
68
69
70
71
72
73





74
75







-
-
-
-
-


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
Changes to doc/FindPhoto.3.
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274







-
+







.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
Currently, if the offset for the alpha channel is greater than or equal to
\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
Changes to doc/FreeXId.3.
21
22
23
24
25
26
27
28



















29
30
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48







-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


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.
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/GetColor.3.
11
12
13
14
15
16
17
18

19
20
21

22
23
24

25
26
27

28
29
30

31
32
33

34
35

36
37


38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
11
12
13
14
15
16
17

18
19
20

21
22
23

24
25
26

27
28
29

30
31
32

33
34

35
36

37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55







-
+


-
+


-
+


-
+


-
+


-
+

-
+

-
+
+









-
+







.SH NAME
Tk_AllocColorFromObj, Tk_GetColor, Tk_GetColorFromObj, Tk_GetColorByValue, Tk_NameOfColor, Tk_FreeColorFromObj, Tk_FreeColor \- maintain database of colors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
XColor *
\fBTk_AllocColorFromObj(\fIinterp, tkwin, objPtr\fB)\fR
\fBTk_AllocColorFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
XColor *
\fBTk_GetColor(\fIinterp, tkwin, name\fB)\fR
\fBTk_GetColor\fR(\fIinterp, tkwin, name\fR)
.sp
XColor *
\fBTk_GetColorFromObj(\fItkwin, objPtr\fB)\fR
\fBTk_GetColorFromObj\fR(\fItkwin, objPtr\fR)
.sp
XColor *
\fBTk_GetColorByValue(\fItkwin, prefPtr\fB)\fR
\fBTk_GetColorByValue\fR(\fItkwin, prefPtr\fR)
.sp
const char *
\fBTk_NameOfColor(\fIcolorPtr\fB)\fR
\fBTk_NameOfColor\fR(\fIcolorPtr\fR)
.sp
GC
\fBTk_GCForColor(\fIcolorPtr, drawable\fB)\fR
\fBTk_GCForColor\fR(\fIcolorPtr, drawable\fR)
.sp
\fBTk_FreeColorFromObj(\fItkwin, objPtr\fB)\fR
\fBTk_FreeColorFromObj\fR(\fItkwin, objPtr\fR)
.sp
\fBTk_FreeColor(\fIcolorPtr\fB)\fR
\fBTk_FreeColor\fR(\fIcolorPtr\fR)
.fi
.SH ARGUMENTS
.AS "Tcl_Interp" *colorPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which color will be used.
.AP Tcl_Obj *objPtr in/out
String value describes desired color; internal rep will be
modified to cache pointer to corresponding (XColor *).
.AP char *name in
.AP "const char" *name in
Same as \fIobjPtr\fR except description of color is passed as a string and
resulting (XColor *) is not cached.
.AP XColor *prefPtr in
Indicates red, green, and blue intensities of desired
color.
.AP XColor *colorPtr in
Pointer to X color information.  Must have been allocated by previous
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93







+










+







.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
\fB#\fIRRGGBB\fR
.TP 20
\fB#\fIRRRGGGBBB\fR
.TP 20
\fB#\fIRRRRGGGGBBBB\fR
.
A numeric specification of the red, green, and blue intensities
to use to display the color.  Each \fIR\fR, \fIG\fR, or \fIB\fR
represents a single hexadecimal digit.  The four forms permit
colors to be specified with 4-bit, 8-bit, 12-bit or 16-bit values.
When fewer than 16 bits are provided for each color, they represent
the most significant bits of the color, while the lower unfilled
bits will be repeatedly replicated from the available higher bits.
Changes to doc/GetCursor.3.
11
12
13
14
15
16
17
18

19
20
21

22
23
24

25
26
27

28
29
30

31
32

33
34


35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
11
12
13
14
15
16
17

18
19
20

21
22
23

24
25
26

27
28
29

30
31

32
33

34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+


-
+


-
+


-
+


-
+

-
+

-
+
+









-
+







.SH NAME
Tk_AllocCursorFromObj, Tk_GetCursor, Tk_GetCursorFromObj, Tk_GetCursorFromData, Tk_NameOfCursor, Tk_FreeCursorFromObj, Tk_FreeCursor \- maintain database of cursors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Cursor
\fBTk_AllocCursorFromObj(\fIinterp, tkwin, objPtr\fB)\fR
\fBTk_AllocCursorFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
Tk_Cursor
\fBTk_GetCursor(\fIinterp, tkwin, name\fB)\fR
\fBTk_GetCursor\fR(\fIinterp, tkwin, name\fR)
.sp
Tk_Cursor
\fBTk_GetCursorFromObj(\fItkwin, objPtr\fB)\fR
\fBTk_GetCursorFromObj\fR(\fItkwin, objPtr\fR)
.sp
Tk_Cursor
\fBTk_GetCursorFromData(\fIinterp, tkwin, source, mask, width, height, xHot, yHot, fg, bg\fB)\fR
\fBTk_GetCursorFromData\fR(\fIinterp, tkwin, source, mask, width, height, xHot, yHot, fg, bg\fR)
.sp
const char *
\fBTk_NameOfCursor(\fIdisplay, cursor\fB)\fR
\fBTk_NameOfCursor\fR(\fIdisplay, cursor\fR)
.sp
\fBTk_FreeCursorFromObj(\fItkwin, objPtr\fB)\fR
\fBTk_FreeCursorFromObj\fR(\fItkwin, objPtr\fR)
.sp
\fBTk_FreeCursor(\fIdisplay, cursor\fB)\fR
\fBTk_FreeCursor\fR(\fIdisplay, cursor\fR)
.fi
.SH ARGUMENTS
.AS "unsigned long" *pixelPtr
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
.AP Tk_Window tkwin in
Token for window in which the cursor will be used.
.AP Tcl_Obj *objPtr in/out
Description of cursor;  see below for possible values.  Internal rep will be
modified to cache pointer to corresponding Tk_Cursor.
.AP char *name in
.AP "const char" *name in
Same as \fIobjPtr\fR except description of cursor is passed as a string and
resulting Tk_Cursor is not cached.
.AP "const char" *source in
Data for cursor cursor, in standard cursor format.
.AP "const char" *mask in
Data for mask cursor, in standard cursor format.
.AP "int" width in
83
84
85
86
87
88
89

90
91
92
93
94
95
96
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98







+







\fBTk_GetCursorFromObj\fR. If an error occurs in creating the cursor,
such as when \fIobjPtr\fR refers to a non-existent file, then \fBNone\fR
is returned and an error message will be stored in \fIinterp\fR's result
if \fIinterp\fR is not NULL.  \fIObjPtr\fR must contain a standard Tcl
list with one of the following forms:
.TP
\fIname\fR\0[\fIfgColor\fR\0[\fIbgColor\fR]]
.
\fIName\fR is the name of a cursor in the standard X cursor cursor,
i.e., any of the names defined in \fBcursorcursor.h\fR, without
the \fBXC_\fR.  Some example values are \fBX_cursor\fR, \fBhand2\fR,
or \fBleft_ptr\fR.  Appendix B of
.QW "The X Window System"
by Scheifler & Gettys has illustrations showing what each of these
cursors looks like.  If \fIfgColor\fR and \fIbgColor\fR are both
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126

127
128
129
130
131
132

133
134
135
136
137
138
139
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144







+









+






+







name of the resource.  The application and all its open
dynamic library's resource files will be searched for the named
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
transparent.  This form of the command will not work on Macintosh
or Windows computers.
.TP
\fB@\fIsourceName\fR
.
This form only works on Windows, and will load a Windows system
cursor (\fB.ani\fR or \fB.cur\fR) from the file specified in
\fIsourceName\fR.
.PP
\fBTk_GetCursor\fR is identical to \fBTk_AllocCursorFromObj\fR except
that the description of the cursor is specified with a string instead
of an object.  This prevents \fBTk_GetCursor\fR from caching the
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211







-
+







The procedure \fBTk_NameOfCursor\fR is roughly the inverse of
\fBTk_GetCursor\fR.  If its \fIcursor\fR argument was created
by \fBTk_GetCursor\fR, then the return value is the \fIname\fR
argument that was passed to \fBTk_GetCursor\fR to create the
cursor.  If \fIcursor\fR was created by a call to \fBTk_GetCursorFromData\fR,
or by any other mechanism, then the return value is a hexadecimal string
giving the X identifier for the cursor.
Note:  the string returned by \fBTk_NameOfCursor\fR is
Note that the string returned by \fBTk_NameOfCursor\fR is
only guaranteed to persist until the next call to
\fBTk_NameOfCursor\fR.  Also, this call is not portable except for
cursors returned by \fBTk_GetCursor\fR.
.PP
When a cursor returned by \fBTk_AllocCursorFromObj\fR, \fBTk_GetCursor\fR,
or \fBTk_GetCursorFromData\fR
is no longer needed, \fBTk_FreeCursorFromObj\fR or
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
1
2
3
4
5
6
7
8
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-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
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
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
84
85
86
87
88
89
90



91
92
93
94
95
96
97







-
-
-







\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.
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
1
2
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, Tk_GetDoublePixelsFromObj \- translate between strings and screen units
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_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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
77
78
79
80
81
82
83



84
85
86
87
88
89
90
91
92
93
94
95







-
-
-












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
Changes to doc/GetRelief.3.
11
12
13
14
15
16
17
18

19
20
21

22
23
24


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
11
12
13
14
15
16
17

18
19
20

21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46


47
48
49
50
51
52
53







-
+


-
+


-
+
+















-
+





-
-







.SH NAME
Tk_GetReliefFromObj, Tk_GetRelief, Tk_NameOfRelief \- translate between strings and relief values
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetReliefFromObj(\fIinterp, objPtr, reliefPtr\fB)\fR
\fBTk_GetReliefFromObj\fR(\fIinterp, objPtr, reliefPtr\fR)
.sp
int
\fBTk_GetRelief(\fIinterp, name, reliefPtr\fB)\fR
\fBTk_GetRelief\fR(\fIinterp, name, reliefPtr\fR)
.sp
const char *
\fBTk_NameOfRelief(\fIrelief\fB)\fR
\fBTk_NameOfRelief\fR(\fIrelief\fR)
.fi
.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
.AP "const char" *name 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.
.AP "const char" *name
Name of the relief.
.AP int relief in
Relief value (one of \fBTK_RELIEF_FLAT\fR, \fBTK_RELIEF_RAISED\fR,
\fBTK_RELIEF_SUNKEN\fR, \fBTK_RELIEF_GROOVE\fR, \fBTK_RELIEF_SOLID\fR,
or \fBTK_RELIEF_RIDGE\fR).
.BE
.SH DESCRIPTION
.PP
Changes to doc/GetScroll.3.
46
47
48
49
50
51
52
53
54


55
56
57

58
59
60
61
62
63
64
65



66
67
68
69
70
71
72
73
46
47
48
49
50
51
52


53
54
55
56

57
58
59
60
61
62



63
64
65

66
67
68
69
70
71
72







-
-
+
+


-
+





-
-
-
+
+
+
-







\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
\fBscroll \fInumber\fB units\fR
\fBscroll \fInumber\fB pages\fR
.CE
.LP
Any of the \fBmoveto\fR, \fBscroll\fR, \fBpages\fR, and \fBunits\fR
Any of the \fBmoveto\fR, \fBscroll\fR, \fBunits\fR, and \fBpages\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,
If \fIobjv\fR has the \fBscroll\fR form, \fBTK_SCROLL_UNITS\fR
or \fBTK_SCROLL_PAGES\fR is returned and \fI*stepsPtr\fR is filled
in with the \fInumber\fR value, which must be a proper integer.
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
Changes to doc/ImgChanged.3.
12
13
14
15
16
17
18
19
20


21
22
23
24
25
26
27
12
13
14
15
16
17
18


19
20
21
22
23
24
25
26
27







-
-
+
+







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
.AS Tk_ImageMaster imageHeight
.AP Tk_ImageMaster 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
43
44
45
46
47
48
49




50
51
52
53
54
55
56
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60







+
+
+
+







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
.VS "TIP 581"
\fITk_ImageModel\fR is synonym for \fITk_ImageMaster\fR
.VE "TIP 581"
.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
Changes to doc/ManageGeom.3.
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54







-
+







.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;
    Tk_GeomLostSlaveProc *\fIlostSlaveProc\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
63
64
65
66
67
68
69
70

71
72

73
74
75

76
77
78
79
80

81
82
83

84
85
86
87

88
89
90
63
64
65
66
67
68
69

70
71

72
73
74

75
76
77
78
79

80
81
82

83
84
85
86

87
88
89
90







-
+

-
+


-
+




-
+


-
+



-
+



.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
The \fIlostSlaveProc\fR field of \fImgrPtr\fR points to another
procedure in the geometry manager.
Tk will invoke \fIlostContentProc\fR if some other manager
Tk will invoke \fIlostSlaveProc\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
\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.
\fIlostContentProc\fR should have
\fIlostSlaveProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void \fBTk_GeomLostContentProc\fR(
typedef void \fBTk_GeomLostSlaveProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostContentProc\fR will be identical to the
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/NameOfImg.3.
10
11
12
13
14
15
16
17

18
19
20


21
22
23
24
25
26
27
28




29
30
10
11
12
13
14
15
16

17
18


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34







-
+

-
-
+
+








+
+
+
+


.SH NAME
Tk_NameOfImage \- Return name of image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_NameOfImage\fR(\fIimageModel\fR)
\fBTk_NameOfImage\fR(\fIimageMaster\fR)
.SH ARGUMENTS
.AS Tk_ImageModel imageModel
.AP Tk_ImageModel imageModel in
.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.
.PP
.VS "TIP 581"
\fITk_ImageModel\fR is synonym for \fITk_ImageMaster\fR
.VE "TIP 581"
.SH KEYWORDS
image manager, image name
Changes to doc/ParseArgv.3.
68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
68
69
70
71
72
73
74


75
76
77
78
79
80
81
82
83







-
-
+
+







.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;
    char *\fIsrc\fR;
    char *\fIdst\fR;
    const char *\fIhelp\fR;
} \fBTk_ArgvInfo\fR;
.CE
The \fIkey\fR field is a string such as
.QW \-display
or
.QW \-bg
308
309
310
311
312
313
314
315

316
317

318
319

320
321

322
323
324
325
326
327
328
308
309
310
311
312
313
314

315
316

317
318

319
320

321
322
323
324
325
326
327
328







-
+

-
+

-
+

-
+







char *fileName = defaultFileName;
Boolean exec = FALSE;

/*
 * Define option descriptions.
 */
Tk_ArgvInfo argTable[] = {
    {"\-X", TK_ARGV_CONSTANT, (char *) 1, &debugFlag,
    {"\-X", TK_ARGV_CONSTANT, (char *) 1, (char *) &debugFlag,
        "Turn on debugging printfs"},
    {"\-N", TK_ARGV_INT, NULL, &numReps,
    {"\-N", TK_ARGV_INT, NULL, (char *) &numReps,
        "Number of repetitions"},
    {"\-of", TK_ARGV_STRING, NULL, &fileName,
    {"\-of", TK_ARGV_STRING, NULL, (char *) &fileName,
        "Name of file for output"},
    {"x", TK_ARGV_REST, NULL, &exec,
    {"x", TK_ARGV_REST, NULL, (char *) &exec,
        "File to exec, followed by any arguments (must be last argument)."},
    {NULL, TK_ARGV_END, NULL, NULL,
        NULL}
};

main(argc, argv)
    int argc;
Changes to doc/SetClassProcs.3.
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43







-
+







.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;
    unsigned int \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.
Changes to doc/SetOptions.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
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16

17
18

19
20
21

22
23
24

25
26

27
28

29
30
31

32
33
34

35
36

37
38
39
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 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
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
\fBTk_CreateOptionTable\fR(\fIinterp, templatePtr\fR)
.sp
\fBTk_DeleteOptionTable(\fIoptionTable\fB)\fR
\fBTk_DeleteOptionTable\fR(\fIoptionTable\fR)
.sp
int
\fBTk_InitOptions(\fIinterp, recordPtr, optionTable, tkwin\fB)\fR
\fBTk_InitOptions\fR(\fIinterp, recordPtr, optionTable, tkwin\fR)
.sp
int
\fBTk_SetOptions(\fIinterp, recordPtr, optionTable, objc, objv, tkwin, savePtr, maskPtr\fB)\fR
\fBTk_SetOptions\fR(\fIinterp, recordPtr, optionTable, objc, objv, tkwin, savePtr, maskPtr\fR)
.sp
\fBTk_FreeSavedOptions(\fIsavedPtr\fB)\fR
\fBTk_FreeSavedOptions\fR(\fIsavedPtr\fR)
.sp
\fBTk_RestoreSavedOptions(\fIsavedPtr\fB)\fR
\fBTk_RestoreSavedOptions\fR(\fIsavedPtr\fR)
.sp
Tcl_Obj *
\fBTk_GetOptionValue(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
\fBTk_GetOptionValue\fR(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fR)
.sp
Tcl_Obj *
\fBTk_GetOptionInfo(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fB)\fR
\fBTk_GetOptionInfo\fR(\fIinterp, recordPtr, optionTable, namePtr, tkwin\fR)
.sp
\fBTk_FreeConfigOptions(\fIrecordPtr, optionTable, tkwin\fB)\fR
\fBTk_FreeConfigOptions\fR(\fIrecordPtr, optionTable, tkwin\fR)
.sp
int
\fBTk_Offset(\fItype, field\fB)\fR
.fi
.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
.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
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112







-
+







.QW widget
will be used to refer to the object whose options are being managed; in
practice the object may not actually be a widget.  The term
.QW "widget record"
is used to refer to the C-level structure in
which information about a particular widget or object is stored.
.PP
Note: the easiest way to learn how to use these procedures is to
Note that the easiest way to learn how to use these procedures is to
look at a working example.  In Tk, the simplest example is the code
that implements the button family of widgets, which is in \fBtkButton.c\fR.
Other examples are in \fBtkSquare.c\fR and \fBtkMenu.c\fR.
.PP
In order to use these procedures, the code that implements the widget
must contain a static array of Tk_OptionSpec structures. This is a
template that describes the various options supported by that class of
123
124
125
126
127
128
129
130

131
132
133
134
135
136

137
138
139
140
141
142
143



144
145
146
147
148
149
150
127
128
129
130
131
132
133

134

135
136
137
138

139

140
141
142
143
144

145
146
147
148
149
150
151
152
153
154







-
+
-




-
+
-





-
+
+
+







class.  A Tk_OptionTable may be used only in a single interpreter, given
by the \fIinterp\fR argument to \fBTk_CreateOptionTable\fR.  When an
option table is no longer needed \fBTk_DeleteOptionTable\fR should be
called to free all of its resources.  All of the option tables
for a Tcl interpreter are freed automatically if the interpreter is deleted.
.PP
\fBTk_InitOptions\fR is invoked when a new widget is created to set the
default values for all of the widget's configuration options that do not
default values.
have \fBTK_OPTION_DONT_SET_DEFAULT\fR set in their \fIflags\fR field.
\fBTk_InitOptions\fR is passed a token for an option table
(\fIoptionTable\fR) and a pointer to a widget record (\fIrecordPtr\fR),
which is the C structure that holds information about this widget.
\fBTk_InitOptions\fR uses the information in the option table to choose an
appropriate default for each option, except those having
appropriate default for each option, then it stores the default value
\fBTK_OPTION_DONT_SET_DEFAULT\fR set, then it stores the default value
directly into the widget record, overwriting any information that was
already present in the widget record.  \fBTk_InitOptions\fR normally
returns \fBTCL_OK\fR.  If an error occurred while setting the default
values (e.g., because a default value was erroneous) then \fBTCL_ERROR\fR
is returned and an error message is left in \fIinterp\fR's result if
\fIinterp\fR is not NULL.
\fIinterp\fR is not NULL. For any widget's configuration option that
has \fBTK_OPTION_DONT_SET_DEFAULT\fR set in its \fIflags\fR field,
the above initialization is fully skipped, see below.
.PP
\fBTk_SetOptions\fR is invoked to modify configuration options based
on information specified in a Tcl command.  The command might be one that
creates a new widget, or a command that modifies options on an existing
widget.  The \fIobjc\fR and \fIobjv\fR arguments describe the
values of the arguments from the Tcl command.  \fIObjv\fR must contain
an even number of objects: the first object of each pair gives the name of
232
233
234
235
236
237
238






239
240
241
242
243
244
245
246
247
248
249
250
251
252
253


254
255
256
257
258
259
260
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261


262
263
264
265
266
267
268
269
270







+
+
+
+
+
+













-
-
+
+







(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;
    size_t \fIobjOffset\fR;
    size_t \fIinternalOffset\fR;
    int \fIobjOffset\fR;
    int \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
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
278
279
280
281
282
283
284

285
286
287
288
289
290
291
292







-
+







\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.
\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
297
298
299
300
301
302
303
304
305

306
307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333


334
335
336
337
338

339
340
341
342
343
344

345
346

347
348



349
350
351
352
353
354
355

356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371

372
373
374
375
376

377
378
379
380
381
382

383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398

399
400
401
402


403
404

405
406
407
408
409

410
411
412
413
414


415
416
417

418
419

420
421
422
423
424


425
426

427
428
429
430
431

432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448

449
450
451
452
453
454
455
307
308
309
310
311
312
313


314
315
316
317
318
319
320
321
322
323
324


325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340


341
342
343
344
345


346
347
348
349
350


351
352

353


354
355
356
357
358
359
360
361


362
363
364
365
366
367


368
369
370
371
372
373
374
375


376
377
378
379


380
381
382
383
384


385
386
387
388
389
390
391
392


393
394
395
396
397
398


399
400
401


402
403


404
405
406
407


408
409
410
411


412
413
414
415

416


417
418
419
420


421
422


423
424
425
426


427
428
429
430
431
432
433
434
435


436
437
438
439
440
441


442
443
444
445
446
447
448
449







-
-
+










-
-
+





+









-
-
+
+



-
-
+




-
-
+

-
+
-
-
+
+
+





-
-
+





-
-
+







-
-
+



-
-
+




-
-
+







-
-
+





-
-
+


-
-
+
+
-
-
+



-
-
+



-
-
+
+


-
+
-
-
+



-
-
+
+
-
-
+



-
-
+








-
-
+





-
-
+







\fBTK_OPTION_INT\fR then the internal form is an integer.  If the
\fIobjOffset\fR or \fIinternalOffset\fR field is negative then the
value is not stored in that form.  At least one of the offsets must be
greater than or equal to zero.
.PP
The \fIflags\fR field consists of one or more bits ORed together. The
following flags are supported:
.TP
\fBTK_OPTION_NULL_OK\fR
.IP \fBTK_OPTION_NULL_OK\fR
If this bit is set for an option then an empty string will be accepted as
the value for the option and the resulting internal form will be a NULL
pointer, a zero value, or \fBNone\fR, depending on the type of the option.
If the flag is not set then empty strings will result in errors.
\fBTK_OPTION_NULL_OK\fR is typically used to allow a
feature to be turned off entirely, e.g. set a cursor value to
\fBNone\fR so that a window simply inherits its parent's cursor.
Not all option types support the \fBTK_OPTION_NULL_OK\fR
flag; for those that do, there is an explicit indication of that fact
in the descriptions below.
.TP
\fBTK_OPTION_DONT_SET_DEFAULT\fR
.IP \fBTK_OPTION_DONT_SET_DEFAULT\fR
If this bit is set for an option then no default value will be set in
\fBTk_InitOptions\fR for this option. Neither the option database, nor any
system default value, nor \fIoptionTable\fR are used to give a default
value to this option. Instead it is assumed that the caller has already
supplied a default value in the widget code.
.RS
.PP
The \fItype\fR field of each Tk_OptionSpec structure determines
how to parse the value of that configuration option. The
legal value for \fItype\fR, and the corresponding actions, are
described below.  If the type requires a \fItkwin\fR value to be
passed into procedures like \fBTk_SetOptions\fR, or if it uses
the \fIclientData\fR field of the Tk_OptionSpec, then it is indicated
explicitly; if not mentioned, the type requires neither \fItkwin\fR
nor \fIclientData\fR.
.TP
\fBTK_OPTION_ANCHOR\fR
.RE
.IP \fBTK_OPTION_ANCHOR\fR
The value must be a standard anchor position such as \fBne\fR or
\fBcenter\fR.  The internal form is a Tk_Anchor value like the ones
returned by \fBTk_GetAnchorFromObj\fR.
.TP
\fBTK_OPTION_BITMAP\fR
.IP \fBTK_OPTION_BITMAP\fR
The value must be a standard Tk bitmap name. The internal form is a
Pixmap token like the ones returned by \fBTk_AllocBitmapFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_BOOLEAN\fR
.IP \fBTK_OPTION_BOOLEAN\fR
The value must be a standard boolean value such as \fBtrue\fR or
\fBno\fR.  The internal form is an integer with value 0 or 1.
\fBno\fR.  The internal form is an integer with value 0 or 1.  Note that if
.TP
\fBTK_OPTION_BORDER\fR
the \fIobjOffset\fR field is not used, information about the original
value of this option will be lost.
.IP \fBTK_OPTION_BORDER\fR
The value must be a standard color name such as \fBred\fR or \fB#ff8080\fR.
The internal form is a Tk_3DBorder token like the ones returned
by \fBTk_Alloc3DBorderFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_COLOR\fR
.IP \fBTK_OPTION_COLOR\fR
The value must be a standard color name such as \fBred\fR or \fB#ff8080\fR.
The internal form is an (XColor *) token like the ones returned by
\fBTk_AllocColorFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_CURSOR\fR
.IP \fBTK_OPTION_CURSOR\fR
The value must be a standard cursor name such as \fBcross\fR or \fB@foo\fR.
The internal form is a Tk_Cursor token like the ones returned by
\fBTk_AllocCursorFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and when the option is set the cursor
for the window is changed by calling \fBXDefineCursor\fR.  This
option type also supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_CUSTOM\fR
.IP \fBTK_OPTION_CUSTOM\fR
This option allows applications to define new option types.  The
clientData field of the entry points to a structure defining the new
option type.  See the section \fBCUSTOM OPTION TYPES\fR below for details.
.TP
\fBTK_OPTION_DOUBLE\fR
.IP \fBTK_OPTION_DOUBLE\fR
The string value must be a floating-point number in
the format accepted by \fBstrtol\fR.  The internal form is a C
\fBdouble\fR value.  This option type supports the \fBTK_OPTION_NULL_OK\fR
flag; if a NULL value is set, the internal representation is set to zero.
.TP
\fBTK_OPTION_END\fR
.IP \fBTK_OPTION_END\fR
Marks the end of the template.  There must be a Tk_OptionSpec structure
with \fItype\fR \fBTK_OPTION_END\fR at the end of each template.  If the
\fIclientData\fR field of this structure is not NULL, then it points to
an additional array of Tk_OptionSpec's, which is itself terminated by
another \fBTK_OPTION_END\fR entry.  Templates may be chained arbitrarily
deeply.  This feature allows common options to be shared by several
widget classes.
.TP
\fBTK_OPTION_FONT\fR
.IP \fBTK_OPTION_FONT\fR
The value must be a standard font name such as \fBTimes 16\fR.
The internal form is a Tk_Font handle like the ones returned by
\fBTk_AllocFontFromObj\fR.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR, and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_INT\fR
.IP \fBTK_OPTION_INT\fR
The string value must be an integer in the format accepted by
\fBstrtol\fR (e.g. \fB0\fR and \fB0x\fR prefixes may be used to
specify octal or hexadecimal numbers, respectively).  The internal
form is a C \fBint\fR value.
specify octal or hexadecimal numbers, respectively).  The internal form is
a C \fBint\fR value.
.TP
\fBTK_OPTION_JUSTIFY\fR
.IP \fBTK_OPTION_JUSTIFY\fR
The value must be a standard justification value such as \fBleft\fR.
The internal form is a Tk_Justify like the values returned by
\fBTk_GetJustifyFromObj\fR.
.TP
\fBTK_OPTION_PIXELS\fR
.IP \fBTK_OPTION_PIXELS\fR
The value must specify a screen distance such as \fB2i\fR or \fB6.4\fR.
The internal form is an integer value giving a
distance in pixels, like the values returned by
\fBTk_GetPixelsFromObj\fR.  Note: if the \fIobjOffset\fR field is not
used then information about the original value of this option will be lost.
\fBTk_GetPixelsFromObj\fR.  Note that if the \fIobjOffset\fR field is not
used, information about the original value of this option will be lost.
See \fBOBJOFFSET VS. INTERNALOFFSET\fR below for details.  This option
type supports the \fBTK_OPTION_NULL_OK\fR flag; if a NULL value is set, the
internal representation is set to zero.
internal representation is set to INT_MIN.
.TP
\fBTK_OPTION_RELIEF\fR
.IP \fBTK_OPTION_RELIEF\fR
The value must be standard relief such as \fBraised\fR.
The internal form is an integer relief value such as
\fBTK_RELIEF_RAISED\fR.  This option type supports the \fBTK_OPTION_NULL_OK\fR
flag; if the empty string is specified as the value for the option,
the integer relief value is set to \fBTK_RELIEF_NULL\fR.
flag; if a NULL value is set, the internal representation is set to
\fBTK_RELIEF_NULL\fR.
.TP
\fBTK_OPTION_STRING\fR
.IP \fBTK_OPTION_STRING\fR
The value may be any string.  The internal form is a (char *) pointer
that points to a dynamically allocated copy of the value.
This option type supports the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fBTK_OPTION_STRING_TABLE\fR
.IP \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
.IP \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.
.TP
\fBTK_OPTION_WINDOW\fR
.IP \fBTK_OPTION_WINDOW\fR
The value must be a window path name.  The internal form is a
\fBTk_Window\fR token for the window.
This option type requires \fItkwin\fR to be supplied to procedures
such as \fBTk_SetOptions\fR (in order to identify the application),
and it supports the \fBTK_OPTION_NULL_OK\fR flag.
.SH "STORAGE MANAGEMENT ISSUES"
.PP
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
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







-
-
+
+







+
+
+
+








-
+







the original screen-independent value. Thus for \fBTK_OPTION_PIXELS\fR options
it is better to use the \fIobjOffset\fR field.  In this case the original
value of the option is retained in the object and can be returned when
the option is retrieved.  In most cases it is convenient to use the
\fIinternalOffset\fR field as well, so that the integer value is
immediately available for use in the widget code (alternatively,
\fBTk_GetPixelsFromObj\fR can be used to extract the integer value from
the object whenever it is needed).  Note: the problem of losing information
on retrievals exists only for \fBTK_OPTION_PIXELS\fR options.
the object whenever it is needed).  Note that the problem of losing
information on retrievals exists only for \fBTK_OPTION_PIXELS\fR options.
.PP
The second reason to use the \fIobjOffset\fR field is in order to
implement new types of options not supported by these procedures.
To implement a new type of option, you can use \fBTK_OPTION_STRING\fR as
the type in the Tk_OptionSpec structure and set the \fIobjOffset\fR field
but not the \fIinternalOffset\fR field.  Then, after calling
\fBTk_SetOptions\fR, convert the object to internal form yourself.
.PP
Ttk widgets do not support the \fIinternalOffset\fR machinery.
Option values of Ttk widgets are always stored as (Tcl_Obj *), meaning that
the \fIobjOffset\fR field must be used.
.SH "CUSTOM OPTION TYPES"
.PP
Applications can extend the built-in configuration types with
additional configuration types by writing procedures to parse, print,
free, and restore saved copies of the type and creating a structure
pointing to those procedures:
.CS
typedef struct Tk_ObjCustomOption {
    char *name;
    const char *\fIname\fR;
    Tk_CustomOptionSetProc *\fIsetProc\fR;
    Tk_CustomOptionGetProc *\fIgetProc\fR;
    Tk_CustomOptionRestoreProc *\fIrestoreProc\fR;
    Tk_CustomOptionFreeProc *\fIfreeProc\fR;
    ClientData \fIclientData\fR;
} \fBTk_ObjCustomOption\fR;

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
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







-
-
+


-
-
+

-
-
+

-
-
+









-
-
+

-
-
+


-
-
+





-
-
+







may be NULL, indicating that no function should be called for those
operations.
.PP
The \fIsetProc\fR procedure is invoked by \fBTk_SetOptions\fR to
convert a Tcl_Obj into an internal representation and store the
resulting value in the widget record.  The arguments are:
.RS
.TP
\fIclientData\fR
.IP \fIclientData\fR
A copy of the \fIclientData\fR field in the Tk_ObjCustomOption
structure.
.TP
\fIinterp\fR
.IP \fIinterp\fR
A pointer to a Tcl interpreter, used for error reporting.
.TP
\fITkwin\fR
.IP \fITkwin\fR
A copy of the \fItkwin\fR argument to \fBTk_SetOptions\fR
.TP
\fIvaluePtr\fR
.IP \fIvaluePtr\fR
A pointer to a reference to a Tcl_Obj describing the new value for the
option; it could have been specified explicitly in the call to
\fBTk_SetOptions\fR or it could come from the option database or a
default.  If the objOffset for the option is non-negative (the option
value is stored as a (Tcl_Obj *) in the widget record), the Tcl_Obj
pointer referenced by \fIvaluePtr\fR is the pointer that will be
stored at the objOffset for the option.  \fISetProc\fR may modify the
value if necessary; for example, \fIsetProc\fR may change the value to
NULL to support the \fBTK_OPTION_NULL_OK\fR flag.
.TP
\fIrecordPtr\fR
.IP \fIrecordPtr\fR
A pointer to the start of the widget record to modify.
.TP
\fIinternalOffset\fR
.IP \fIinternalOffset\fR
Offset in bytes from the start of the widget record to the location
where the internal representation of the option value is to be placed.
.TP
\fIsaveInternalPtr\fR
.IP \fIsaveInternalPtr\fR
A pointer to storage allocated in a Tk_SavedOptions structure for the
internal representation of the original option value.  Before setting
the option to its new value, \fIsetProc\fR should set the value
referenced by \fIsaveInternalPtr\fR to the original value of the
option in order to support \fBTk_RestoreSavedOptions\fR.
.TP
\fIflags\fR
.IP \fIflags\fR
A copy of the \fIflags\fR field in the Tk_OptionSpec structure for the
option
.RE
.PP
\fISetProc\fR returns a standard Tcl result: \fBTCL_OK\fR to indicate successful
processing, or \fBTCL_ERROR\fR to indicate a failure of any kind.  An error
message may be left in the Tcl interpreter given by \fIinterp\fR in
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
1
2
3
4
5
6
7
8
9
10
11

12
13
14
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_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
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
int
\fBTk_AlwaysShowSelection\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
93
94
95
96
97
98
99



100
101
102
103
104
105
106







-
-
-







\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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
123
124
125
126
127
128
129


130
131
132
133
134
135
136







-
-







.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
186
187
188
189
190
191
192
193
194
195
196
197
198
178
179
180
181
182
183
184


185
186
187
188







-
-




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
Changes to doc/bind.n.
49
50
51
52
53
54
55



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80







+
+
+




-
-
-










-
+







the window.
Although the \fBbindtags\fR command may be used to assign an
arbitrary set of binding tags to a window, the default binding
tags provide the following behavior:
.IP \(bu 3
If a tag is the name of an internal window the binding applies
to that window.
.IP \(bu 3
If the tag is the name of a class of widgets, such as \fBButton\fR,
the binding applies to all widgets in that class.
.IP \(bu 3
If the tag is the name of a toplevel window the binding applies
to the toplevel window and all its internal windows.
.IP \(bu 3
If the tag is the name of a class of widgets, such as \fBButton\fR,
the binding applies to all widgets in that class;
.IP \(bu 3
If \fItag\fR has the value \fBall\fR,
the binding applies to all windows in the application.
.SH "EVENT PATTERNS"
.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
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
164
165
166
167
168
169
170
171

172
173

174
175
176
177
178

179
180
181
182
183
184
185
164
165
166
167
168
169
170

171
172

173
174
175
176
177

178
179
180
181
182
183
184
185







-
+

-
+




-
+







.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
.ta \w'\fBButtonPress, Button\0\0\0\fR'u +\w'\fBKeyPress, Key\0\0\0\fR'u
\fBActivate\fR	\fBDestroy\fR	\fBMap\fR
\fBButton\fR, \fBButtonPress\fR	\fBEnter\fR	\fBMapRequest\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	\fBKey\fR, \fBKeyPress\fR	\fBResizeRequest\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
210
211
212
213
214
215
216




217

218
219
220
221
222
223
224
225
226
227
228
229


230
231
232

233
234
235
236
237
238

239
240
241
242
243
244
245
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227



228


229
230
231
232

233
234
235
236
237
238

239
240
241
242
243
244
245
246







+
+
+
+
-
+






-
-
-

-
-
+
+


-
+





-
+







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.
Only Windows and macOS Aqua typically fire \fBMouseWheel\fR and
\fBShift-MouseWheel\fR events.  On
X11 vertical scrolling is rather supported through \fBButton-4\fR and
\fBButton-5\fR events, and horizontal scrolling through \fBShift-Button-4\fR
Horizontal scrolling events may fire from
and \fBShift-Button-5\fR events.  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
.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.
\fBButton\fR, \fBButtonRelease\fR, and \fBMotion\fR events are
\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 \fBButton\fR, \fBButtonRelease\fR, and \fBMotion\fR
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
360
361
362
363
364
365
366
367
368


369
370
371
372
373
374
375
376
377


378
379

380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401

402
403
404
405
406
407
408
361
362
363
364
365
366
367


368
369
370
371
372
373
374
375
376


377
378
379

380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401

402
403
404
405
406
407
408
409







-
-
+
+







-
-
+
+

-
+



















-
+

-
+







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
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 \fBButton\fR.  For example, the specifier \fB<1>\fR
is equivalent to \fB<Button\-1>\fR.
to \fBButtonPress\fR.  For example, the specifier \fB<1>\fR
is equivalent to \fB<ButtonPress\-1>\fR.
.PP
If the event type is \fBKey\fR or \fBKeyRelease\fR, then
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 \fBKey\fR.
\fItype\fR field may be omitted;  it will default to \fBKeyPress\fR.
For example, \fB<Control\-comma>\fR is equivalent to
\fB<Control\-Key\-comma>\fR.
\fB<Control\-KeyPress\-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
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445







-
+







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.
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 or \fIuser_data\fR
field from the event.  The \fB%d\fR is replaced by
477
478
479
480
481
482
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
478
479
480
481
482
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







-
+














-
-
+
+







\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
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 \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBKey\fR, \fBKeyRelease\fR,
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
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







-
-
+
+















-
-
+
+

















-
+





-
+







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,
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 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.
On X11, valid only for \fBKeyPress\fR event. On Windows and macOS/aqua,
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. 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.
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 \fBKey\fR and \fBKeyRelease\fR events.
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
580
581
582
583
584
585
586

587
588
589
590
591
592
593
594







-
+







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,
\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
646
647
648
649
650
651
652
653
654


655
656
657
658
659
660
661
662
647
648
649
650
651
652
653


654
655

656
657
658
659
660
661
662







-
-
+
+
-







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
a longer sequence (in terms of number
of events matched) is more specific than a shorter sequence;
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
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
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







-
+



-
-
+
+


-
-
-
+
+
+







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
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 \fBKey\fR or \fBButton\fR events.
For example, \fB<Double\-Button\-1>\fR will match a sequence of
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
\fBButton\fR events.
Furthermore, a \fBKey\fR event may be preceded by any number
of other \fBKey\fR events for modifier keys without 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.
Changes to doc/bitmap.n.
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100







-
+







.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?
\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
.
Changes to doc/busy.n.
26
27
28
29
30
31
32

33

34
35
36
37

38
39
40
41

42
43
44
45

46
47
48
49
50
51
52
26
27
28
29
30
31
32
33

34




35

36


37

38

39
40
41
42
43
44
45
46
47







+
-
+
-
-
-
-
+
-

-
-
+
-

-

+







.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
.nf
\fBtk busy\fR \fIwindow \fR?\fIoptions\fR?
\fBtk busy\fI window \fR?\fIoptions\fR?
.sp
\fBtk busy busywindow \fIwindow\fR
.sp
\fBtk busy hold\fR \fIwindow \fR?\fIoptions\fR?
\fBtk busy hold\fI window \fR?\fIoptions\fR?
.sp
\fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...
.sp
\fBtk busy forget\fR \fIwindow \fR?\fIwindow \fR?...
\fBtk busy forget\fI window \fR?\fIwindow \fR?...
.sp
\fBtk busy current\fR ?\fIpattern\fR?
.sp
\fBtk busy status \fIwindow\fR
.fi
.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.
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139

140
141
142
143
144
145

146
147
148
149
150
151
152
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126



127



128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143







-
+












-
-
-
+
-
-
-

-
+






+







\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"
\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
.
.\" METHOD: cget
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
\fBtk busy cget \fIwindow option\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.
.\" METHOD: configure
.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
165
166
167
168
169
170
171

172
173
174
175
176
177

178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193
194
195
196
197
198

199

200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226

227














228
229
230


231
232
233
234
235
236
237
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218
219
220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236


237
238
239
240
241
242
243
244
245







+






+








+










-
-
-
+

+







+

















-
+


+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+







specified for it by either \fBoption\fR command:
.PP
.CS
option add *frame.busyCursor gumby
option add *Frame.BusyCursor gumby
.CE
.RE
.\" METHOD: current
.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.
.\" METHOD: forget
.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.
.\" METHOD: hold
.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:
following configuration options are valid:
.RS
.\" OPTION: -cursor
.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
.\" METHOD: status
.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> { ... }
bind .frame.canvas_Busy <Enter> { ... }
.CE
.PP
Normally the busy window is a sibling of the widget. The name of the busy
or
window is
.QW \fIwidget\fB_Busy\fR
where \fIwidget\fR is the name of the widget to be made busy. In the previous
example, the pathname of the busy window is
.QW \fB.frame.canvas_Busy\fR .
The exception is when the widget is a toplevel widget (such as
.QW . )
where the busy window can't be made a sibling. The busy window is then a child
of the widget named
.QW \fIwidget\fB._Busy\fR
where \fIwidget\fR is the name of the toplevel widget. In the following
example, the pathname of the busy window is
.QW \fB._Busy\fR .
.PP
.CS
set busyWin [\fBtk busy\fR hold .frame.canvas]
bind $busyWin <Enter> { ... }
\fBtk busy\fR hold .
bind ._Busy <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"
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279







-
+








.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
Note that the \fBtk busy\fR command does not currently have any effect on macOS
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.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\fBbutton\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-font	\-relief
\-activeforeground	\-foreground	\-repeatdelay
\-anchor	\-highlightbackground	\-repeatinterval
\-background	\-highlightcolor	\-takefocus
\-bitmap	\-highlightthickness	\-text
\-borderwidth	\-image	\-textvariable
110
111
112
113
114
115
116

117
118


119
120
121
122

123
124

125
126
127
128
129
130
131
132
133
134
135
136

137
138

139
140
141
142
143

144
145

146
147
148
149
150
151
152
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160







+

-
+
+




+


+












+


+





+


+







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:
.\" METHOD: cget
.TP
\fIpathName \fBcget\fR \fIoption\fR
\fIpathName \fBcget\fI option\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBbutton\fR
command.
.\" METHOD: configure
.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 \fBbutton\fR
command.
.\" METHOD: flash
.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.
.\" METHOD: invoke
.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
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201




202
203
204
205
206
207
208
209
210
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205




206
207
208
209
210
211
212
213
214
215
216
217
218







-
+












-
+






-
-
-
-
+
+
+
+









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
On Aqua/macOS, 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
\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}
\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:
Changes to doc/canvas.n.
216
217
218
219
220
221
222
223

224
225
226
227
228

229
230
231
232
233
234
235
216
217
218
219
220
221
222

223





224
225
226
227
228
229
230
231







-
+
-
-
-
-
-
+







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
Individual items may be moved or scaled using widget commands
.VS "8.7, TIP164"
or rotated
.VE "8.7, TIP164"
using widget commands
described below.
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
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
309
310
311
312
313
314
315

316
317
318
319
320
321
322







-







.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}
344
345
346
347
348
349
350
351

352
353
354
355
356
357

358
359
360
361
362
363
364
339
340
341
342
343
344
345

346
347
348
349
350
351

352
353
354
355
356
357
358
359







-
+





-
+







.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?
\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 ...\fR?
\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
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475







-
+







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.
\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
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607







-
+







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?
\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.
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
654
655
656
657
658
659
660














661

662
663
664
665
666
667
668
669
670
671
672
673
674
675







-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+





+







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
.
.VS 8.6
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.
.VE 8.6
.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.
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
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







-
+









+







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
.
.VS 8.6
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.
.VE 8.6
.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.
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
943
944
945
946
947
948
949

950
951
952
953
954
955
956
957
958





















959
960
961
962
963
964
965
966







-
+








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







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
.
.VS 8.6
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"
.VE 8.6
.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
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
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







-
+
-
-
+

+
+
+





-
-
-







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
\fINumber\fR must be an integer.
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
\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.
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:
1186
1187
1188
1189
1190
1191
1192
1193




1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1162
1163



1164
1165
1166
1167
1168
1169
1170







-
+
+
+
+





-
-
-







\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.
\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.
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
1252
1253
1254
1255
1256
1257
1258
1259


1260
1261
1262
1263
1264
1265
1266
1214
1215
1216
1217
1218
1219
1220

1221
1222
1223
1224
1225
1226
1227
1228
1229







-
+
+







\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,
in its normal, active, and disabled states.
The even-odd fill rule is used.
\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
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
1321
1322
1323
1324
1325
1326
1327


1328
1329
1330
1331
1332
1333
1334
1335
1336

1337


1338
1339
1340
1341
1342
1343
1344







-
-
+
+







-
+
-
-







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).
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 ...\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
rectangular region enclosing the oval that defines the arc.
\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.
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
1370
1371
1372
1373
1374
1375
1376




























1377
1378
1379
1380
1381
1382
1383







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







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
1760
1761
1762
1763
1764
1765
1766
1767

1768
1769
1770
1771
1772
1773
1774
1693
1694
1695
1696
1697
1698
1699

1700
1701
1702
1703
1704
1705
1706
1707







-
+







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
line segments can be generated 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
1859
1860
1861
1862
1863
1864
1865
1866

1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1792
1793
1794
1795
1796
1797
1798

1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812







-
+





+







\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
.
.VS 8.6
\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.
.VE 8.6
.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
Changes to doc/checkbutton.n.
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202







-
+







.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?
\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
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
1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26

27
28
29

30
31
32
33
34
35
36
37
38
39
40
41

42
43
44

45
46
47

48
49
50
51
52
53
54

55
56
57

58
59
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) 1998-2000 by Scriptics Corporation.
'\" Copyright (c) 1998-2000 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:
.\" OPTION: -command
.TP
\fB\-command\fR \fIstring\fR
\fB\-command\fI string\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.
is only available on macOS.
.\" OPTION: -initialdir
.TP
\fB\-initialdir\fR \fIdirname\fR
\fB\-initialdir\fI dirname\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.
.\" OPTION: -message
.TP
\fB\-message\fR \fIstring\fR
\fB\-message\fI string\fR
.
Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.
This is only available on macOS.
.\" OPTION: -mustexist
.TP
\fB\-mustexist\fR \fIboolean\fR
\fB\-mustexist\fI boolean\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.
.\" OPTION: -parent
.TP
\fB\-parent\fR \fIwindow\fR
\fB\-parent\fI window\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
is displayed on top of its parent window. On macOS, this
turns the file dialog into a sheet attached to the parent window.
.\" OPTION: -title
.TP
\fB\-title\fR \fItitleString\fR
\fB\-title\fI titleString\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"]
        -initialdir ~ -title "Choose a directory"]
if {$dir eq ""} {
   label .l \-text "No directory selected"
   label .l -text "No directory selected"
} else {
   label .l \-text "Selected $dir"
   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:
Changes to doc/clipboard.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\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
Changes to doc/colors.n.
1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" Copyright (c) 1998-2000 Scriptics Corporation.
'\" Copyright (c) 2003 ActiveState Corporation.
'\" Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
'\" Copyright (c) 2008 Donal K. Fellows
'\"
.TH colors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
778
779
780
781
782
783
784
785

786
787
788
789
790
791
792
778
779
780
781
782
783
784

785
786
787
788
789
790
791
792







-
+







yellow2	238	238 	0
yellow3	205	205 	0
yellow4	139	139 	0
YellowGreen	154	205 	50
.DE
.SH "PORTABILITY ISSUES"
.TP
\fBMac OS X\fR
\fBmacOS\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
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
866
867
868
869
870
871
872

873
874
875
876
877
878
879
880







-
+







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
capitalizing the macOS name and adding the prefix "system".  On macOS
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.
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
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







-
+














-







-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+




-









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
to provide a contrasting background.  Each numbered color contrasts
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
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
systemHighlight
.DE
.RE
.SH "SEE ALSO"
options(n), Tk_GetColor(3)
.SH KEYWORDS
color, option
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/cursors.n.
1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" Copyright (c) 1998-2000 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
97
98
99
100
101
102
103

104
105
106
107
108
109
110
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111







+







xterm
.CE
.PP
The \fBnone\fR cursor can be specified to eliminate the cursor.
.SH "PORTABILITY ISSUES"
.TP
\fBWindows\fR
.
On Windows systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow
center_ptr
crosshair
fleur
126
127
128
129
130
131
132
133
134



135
136
137
138
139
140
141
127
128
129
130
131
132
133


134
135
136
137
138
139
140
141
142
143







-
-
+
+
+







size_nw_se
size_we
uparrow
wait
.CE
.RE
.TP
\fBMac OS X\fR
On Mac OS X systems, the following cursors are mapped to native cursors:
\fBmacOS\fR
.
On macOS, the following cursors are mapped to native cursors:
.RS
.CS
arrow
top_left_arrow
left_ptr
cross
crosshair
Changes to doc/entry.n.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
19
20
21
22
23
24
25

26
27
28
29
30
31
32







-







\-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
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199







-
+







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?
\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
399
400
401
402
403
404
405
406

407
408

409


410
411
412



413
414
415
416
417
418
419
420
421
422
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 or a float, but if it is a float then
\fINumber\fR must be an integer.
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
\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
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
\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
Changes to doc/event.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\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:
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110







-
+







\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
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.
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173







-
+







-
+







\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.
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 \fBKey\fR and \fBKeyRelease\fR events.
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
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200

201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199

200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259







-
+







-
+






-
+
















-
+











-
+







-
+







-
+







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,
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 \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
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 \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
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 \fBKey\fR, \fBKeyRelease\fR, \fBButtons\fR,
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 \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
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. 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,
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 \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
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
278
279
280
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 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,
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 \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
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.
338
339
340
341
342
343
344









345
346
347
348
349
350
351
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360







+
+
+
+
+
+
+
+
+







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<<TkWorldChanged>>\fR
.
This event is sent to all widgets when a font is changed, for example,
by the use of [font configure].  The user_data field (%d) will have the
value "FontChanged".  For other system wide changes, this event will
be sent to all widgets, and the user_data field will indicate the
cause of the change.  NOTE: all tk and ttk widgets already handle this
event internally.
.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
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587







-
+







.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>
\fBevent add\fR <<Paste>> <Key-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.
Changes to doc/focus.n.
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25







-
+







'\" 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?
\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
Changes to doc/font.n.
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60

61
62
63
64
65
66
67
68
69

70
71

72
73
74
75
76
77
78

79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109

110
111

112
113
114
115
116
117
118
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127







+


















+














-
+





+









+

-
+







+






+














+











+


+







.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:
.\" METHOD: actual
.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.
.\" METHOD: configure
.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
Note that on Aqua/macOS, 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
.\" METHOD: create
.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
the new named font.  See \fBFONT OPTIONS\fR below for a list of the possible
attributes.
.\" METHOD: delete
.TP
\fBfont delete\fR \fIfontname\fR ?\fIfontname ...\fR?
\fBfont delete\fI fontname\fR ?\fIfontname ...\fR?
.
Delete the specified named fonts.  If there are widgets using the named font,
the named font will not actually be deleted until all the instances are
released.  Those widgets will continue to display using the last known values
for the named font.  If a deleted named font is subsequently recreated with
another call to \fBfont create\fR, the widgets will use the new named font
and redisplay themselves using the new attributes of that font.
.\" METHOD: families
.TP
\fBfont families\fR ?\fB\-displayof \fIwindow\fR?
.
The return value is a list of the case-insensitive names of all font families
that exist on \fIwindow\fR's display.  If the \fIwindow\fR argument is
omitted, it defaults to the main window.
.\" METHOD: measure
.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.
.\" METHOD: metrics
.TP
\fBfont metrics \fIfont\fR ?\fB\-displayof \fIwindow\fR? ?\fIoption\fR?
.
Returns information about the metrics (the font-specific data), for
\fIfont\fR when it is used on \fIwindow\fR's display.  \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 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.
.\" METHOD: names
.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
196
197
198
199
200
201
202

203
204

205
206
207

208
209

210
211
212

213
214
215
216
217
218
219

220
221

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279

280
281

282
283
284
285
286
287

288
289

290
291

292
293

294
295
296
297
298
299
300
301
302

303
304
305
306

307
308
309
310

311
312
313
314

315
316
317
318

319
320
321
322

323
324
325
326

327
328
329
330

331
332
333
334

335
336
337
338
339
340
341
342
343
344
345

346
347
348

349
350
351
352
353
354
355
356
357
358
359


360
361
362
363
364
365
366
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322


323

324


325

326


327

328


329

330


331

332


333

334


335

336


337

338


339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373







+

-
+



+

-
+



+







+

-
+
















+
















+



















+







+


+






+


+


+


+







-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-

-
-
+
-










+



+










-
+
+







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,
such as lower-case
.QW g
stick below the baseline.
.\" OPTION: -ascent
.TP
\fB\-ascent        \0\fR
\fB\-ascent\fR
.
The amount in pixels that the tallest letter sticks up above the baseline of
the font, plus any extra blank space added by the designer of the font.
.\" OPTION: -descent
.TP
\fB\-descent       \0\fR
\fB\-descent\fR
.
The largest amount in pixels that any letter sticks down below the baseline
of the font, plus any extra blank space added by the designer of the font.
.\" OPTION: -linespace
.TP
\fB\-linespace\fR
.
Returns how far apart vertically in pixels two lines of text using the same
font should be placed so that none of the characters in one line overlap any
of the characters in the other line.  This is generally the sum of the ascent
above the baseline line plus the descent below the baseline.
.\" OPTION: -fixed
.TP
\fB\-fixed          \0\fR
\fB\-fixed\fR
.
Returns a boolean flag that is
.QW \fB1\fR
if this is a fixed-width font,
where each normal character is the same width as all the other
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:
.\" OPTION: -family
.TP
\fB\-family \fIname\fR
.
The case-insensitive font family name.  Tk guarantees to support the font
families named \fBCourier\fR (a monospaced
.QW typewriter
font), \fBTimes\fR (a serifed
.QW newspaper
font), and \fBHelvetica\fR (a sans-serif
.QW European
font).  The most closely matching native font family will
automatically be substituted when one of the above font families is used.
The \fIname\fR may also be the name of a native, platform-specific font
family; in that case it will work as desired on one platform but may not
display correctly on other platforms.  If the family is unspecified or
unrecognized, a platform-specific default font will be chosen.
.\" OPTION: -size
.TP
\fB\-size \fIsize\fR
.
The desired size of the font.  If the \fIsize\fR argument is a positive
number, it is interpreted as a size in points.  If \fIsize\fR is a negative
number, its absolute value is interpreted as a size in pixels.  If a
font cannot be displayed at the specified size, a nearby size will be
chosen.  If \fIsize\fR is unspecified or zero, a platform-dependent default
size will be chosen.
.RS
.PP
Sizes should normally be specified in points so the application will remain
the same ruler size on the screen, even when changing screen resolutions or
moving scripts across platforms.  However, specifying pixels is useful in
certain circumstances such as when a piece of text must line up with respect
to a fixed-size bitmap.  The mapping between points and pixels is set when
the application starts, based on properties of the installed monitor, but it
can be overridden by calling the \fBtk scaling\fR command.
.RE
.\" OPTION: -weight
.TP
\fB\-weight \fIweight\fR
.
The nominal thickness of the characters in the font.  The value
\fBnormal\fR specifies a normal weight font, while \fBbold\fR specifies a
bold font.  The closest available weight to the one specified will
be chosen.  The default weight is \fBnormal\fR.
.\" OPTION: -slant
.TP
\fB\-slant \fIslant\fR
.
The amount the characters in the font are slanted away from the
vertical.  Valid values for slant are \fBroman\fR and \fBitalic\fR.
A roman font is the normal, upright appearance of a font, while
an italic font is one that is tilted some number of degrees from upright.
The closest available slant to the one specified will be chosen.
The default slant is \fBroman\fR.
.\" OPTION: -underline
.TP
\fB\-underline \fIboolean\fR
.
The value is a boolean flag that specifies whether characters in this
font should be underlined.  The default value for underline is \fBfalse\fR.
.\" OPTION: -overstrike
.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
.IP \fBTkDefaultFont\fR
.
This font is the default for all GUI items not otherwise specified.
.TP
\fBTkTextFont\fR
.IP \fBTkTextFont\fR
.
This font should be used for user text in entry widgets, listboxes etc.
.TP
\fBTkFixedFont\fR
.IP \fBTkFixedFont\fR
.
This font is the standard fixed-width font.
.TP
\fBTkMenuFont\fR
.IP \fBTkMenuFont\fR
.
This font is used for menu items.
.TP
\fBTkHeadingFont\fR
.IP \fBTkHeadingFont\fR
.
This font should be used for column headings in lists and tables.
.TP
\fBTkCaptionFont\fR
.IP \fBTkCaptionFont\fR
.
This font should be used for window and dialog caption bars.
.TP
\fBTkSmallCaptionFont\fR
.IP \fBTkSmallCaptionFont\fR
.
This font should be used for captions on contained windows or tool dialogs.
.TP
\fBTkIconFont\fR
.IP \fBTkIconFont\fR
.
This font should be used for icon captions.
.TP
\fBTkTooltipFont\fR
.IP \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
.
The following fonts are supported, and are mapped to the user's
style defaults.
.RS
.DS
.ta 3c 6c
\fBsystem\fR	\fBansi\fR	\fBdevice\fR
\fBsystemfixed\fR	\fBansifixed\fR	\fBoemfixed\fR
.DE
.RE
.TP
\fBMac OS X\fR
\fBmacOS\fR
.
The following fonts are supported, and are mapped to the user's
style defaults.
.RS
.DS
.ta 3c 6c
\fBsystem\fR	\fBapplication\fR	\fBmenu\fR
.DE
382
383
384
385
386
387
388
389

390
391
392
393
394



395
396
397
398
399




400
401
402
403
404
405
406
407
408
409
389
390
391
392
393
394
395

396
397
398



399
400
401
402




403
404
405
406
407
408
409
410
411
412
413
414
415
416







-
+


-
-
-
+
+
+

-
-
-
-
+
+
+
+










.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
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
foreach family [lsort -dictionary [\fBfont families\fR]] {
    .t tag configure f[incr count] -font [list $family 10]
    .t insert end ${family}:\et {} \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
    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:
Changes to 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16

17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131













+

-

-

+








-
+





+





+





+







+


+



+


+


+


+





+


+









+


+







+








+















-
+







'\"
'\" 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
.nf
\fBtk fontchooser\fR \fBconfigure\fR ?\fI\-option value ...\fR?
.sp
\fBtk fontchooser\fR \fBshow\fR
.sp
\fBtk fontchooser\fR \fBhide\fR
.fi
.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
return an immediate result, as on some platforms (macOS) 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:
.\" METHOD: configure
.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).
.\" METHOD: show
.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.
.\" METHOD: hide
.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"
.\" OPTION: -parent
.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.
.\" OPTION: -title
.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.
.\" OPTION: -font
.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.
.\" OPTION: -command
.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).
.\" OPTION: -visible
.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
other user actions may also have that effect; on macOS 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
135
136
137
138
139
140
141
142
143


144
145

146
147
148

149
150
151
152
153


154
155
156
157
158

159
160
161
162
163


164
165
166
167
168


169
170
171

172
173
174
175
176
177
178
179
180
181
150
151
152
153
154
155
156


157
158
159

160
161
162

163
164
165
166


167
168
169
170
171
172

173
174
175
176


177
178
179
180
181


182
183
184
185

186
187
188
189
190
191
192
193
194
195
196







-
-
+
+

-
+


-
+



-
-
+
+




-
+



-
-
+
+



-
-
+
+


-
+










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
    \fBtk fontchooser\fR \fBconfigure\fR -parent .
    button .b -command fontchooserToggle -takefocus 0
    fontchooserVisibility .b
    bind . \fB<<TkFontchooserVisibility>>\fR \\
    bind . \fB<<TkFontchooserVisibility>>\fR \e
            [list fontchooserVisibility .b]
    foreach w {.t1 .t2} {
        text $w \-width 20 \-height 4 \-borderwidth 1 \-relief solid
        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}
    .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] ?
            [\fBtk fontchooser\fR \fBconfigure\fR -visible] ?
            "\fBhide\fR" : "\fBshow\fR"}]
}
proc fontchooserVisibility {w} {
    $w configure \-text [expr {
            [\fBtk fontchooser\fR \fBconfigure\fR \-visible] ?
    $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]
    \fBtk fontchooser\fR \fBconfigure\fR -font [$w cget -font] \e
            -command [list fontchooserFontSelection $w]
}
proc fontchooserFontSelection {w font args} {
    $w configure \-font [font actual $font]
    $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.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
21
22
23
24
25
26
27










28
29
30
31
32
33
34







-
-
-
-
-
-
-
-
-
-







.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.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
58
59
60
61
62
63
64









65
66
67
68
69
70
71







-
-
-
-
-
-
-
-
-







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.
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111







-
+









-
+







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
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:
.PP
.CS
\fIpathName option \fR?\fIarg ...\fR?
\fIpathName option \fR?\fIarg arg ...\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
Changes to doc/getOpenFile.n.
30
31
32
33
34
35
36

37
38


39
40
41
42
43


44
45


46
47
48
49

50
51

52
53
54
55
56

57
58
59

60
61

62
63
64
65
66
67
68
69
70

71
72

73
74
75
76
77
78
79
80
81

82
83

84
85

86
87

88
89
90


91
92

93
94

95
96

97
98
99

100

101
102

103
104
105

106
107

108
109
110
111
112
113
114
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
55

56
57
58
59
60

61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95

96
97
98

99
100
101

102
103
104
105
106

107
108
109

110
111
112
113

114
115
116
117
118
119

120
121
122
123
124
125
126
127







+

-
+
+




-
+
+

-
+
+




+

-
+




-
+



+

-
+









+

-
+









+

-
+


+

-
+


-
+
+

-
+


+

-
+


-
+

+

-
+



+

-
+







The \fBtk_getSaveFile\fR command is usually associated with the \fBSave
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:
.\" OPTION: -command
.TP
\fB\-command\fR \fIstring\fR
\fB\-command\fI string\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.
is only available on macOS.
.\" OPTION: -confirmoverwrite
.TP
\fB\-confirmoverwrite\fR \fIboolean\fR
\fB\-confirmoverwrite\fI boolean\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.
.\" OPTION: -defaultextension
.TP
\fB\-defaultextension\fR \fIextension\fR
\fB\-defaultextension\fI extension\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
any case. This option is ignored on macOS, 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.
.\" OPTION: -filetypes
.TP
\fB\-filetypes\fR \fIfilePatternList\fR
\fB\-filetypes\fI filePatternList\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.
.\" OPTION: -initialdir
.TP
\fB\-initialdir\fR \fIdirectory\fR
\fB\-initialdir\fI directory\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.
.\" OPTION: -initialfile
.TP
\fB\-initialfile\fR \fIfilename\fR
\fB\-initialfile\fI filename\fR
.
Specifies a filename to be displayed in the dialog when it pops up.
.\" OPTION: -message
.TP
\fB\-message\fR \fIstring\fR
\fB\-message\fI string\fR
.
Specifies a message to include in the client area of the dialog.
This is only available on Mac OS X.
This is only available on macOS.
.\" OPTION: -multiple
.TP
\fB\-multiple\fR \fIboolean\fR
\fB\-multiple\fI boolean\fR
.
Allows the user to choose multiple files from the Open dialog.
.\" OPTION: -parent
.TP
\fB\-parent\fR \fIwindow\fR
\fB\-parent\fI window\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
dialog is displayed on top of its parent window. On macOS, this
turns the file dialog into a sheet attached to the parent window.
.\" OPTION: -title
.TP
\fB\-title\fR \fItitleString\fR
\fB\-title\fI titleString\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.
.\" OPTION: -typevariable
.TP
\fB\-typevariable\fR \fIvariableName\fR
\fB\-typevariable\fI variableName\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
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220







-
+












    {{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]
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:
Changes to doc/grab.n.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







.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...?
\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
Changes to doc/grid.n.
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187







-
+







.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
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 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.
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
198
199
200
201
202
203
204








205
206
207
208
209
210
211







-
-
-
-
-
-
-
-







.
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
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245







-
+







\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.
geometry window, \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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307

308
309
310

311
312

313
314


315
316
317
318
319
320
321
273
274
275
276
277
278
279








280
281
282
283
284
285
286
287

288
289
290

291
292
293
294
295
296

297
298

299
300
301
302
303
304
305
306
307







-
-
-
-
-
-
-
-








-
+


-
+



+

-
+

-
+
+







.
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?
\fBgrid slaves \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.
are 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.
.VS "TIP 581"
.TP
\fBgrid slaves \fIwindow\fR ?\fI\-option value\fR?
\fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.
Synonym for . \fBgrid content \fIwindow\fR ?\fI\-option value\fR?
Synonym for \fBgrid slaves \fIwindow\fR ?\fI\-option value\fR?.
.VE "TIP 581"
.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.
Changes to doc/image.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\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
Changes to doc/keysyms.n.
1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" Copyright (c) 1998-2000 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
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148


149
150
151
152
153
154
155
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146


147
148
149
150
151
152
153
154
155







-
+














-
-
+
+







currency                           164     0xA4
yen                                165     0xA5
brokenbar                          166     0xA6
section                            167     0xA7
diaeresis                          168     0xA8
copyright                          169     0xA9
ordfeminine                        170     0xAA
guillemotleft                      171     0xAB
guillemetleft                      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
ordmasculine                       186     0xBA
guillemetright                     187     0xBB
onequarter                         188     0xBC
onehalf                            189     0xBD
threequarters                      190     0xBE
questiondown                       191     0xBF
Agrave                             192     0xC0
Aacute                             193     0xC1
Acircumflex                        194     0xC2
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396


397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227


228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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







+
+









-
-









































































































































































+
+



































-
-

















































































































+



+































































+
+























-
-





















































































































































































+
+







ugrave                             249     0xF9
uacute                             250     0xFA
ucircumflex                        251     0xFB
udiaeresis                         252     0xFC
yacute                             253     0xFD
thorn                              254     0xFE
ydiaeresis                         255     0xFF
.CE
.CS
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
.CE
.CS
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_IOTAaccentdiaeresis         1958     0x7A6
Greek_OMICRONaccent               1959     0x7A7
Greek_UPSILONaccent               1960     0x7A8
Greek_UPSILONdieresis             1961     0x7A9
Greek_UPSILONaccentdieresis       1962     0x7AA
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
.CE
.CS
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
.CE
.CS
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
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
994
995
996
997
998
999
1000

1001






























1002
1003
1004
1005
1006
1007
1008
1009







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







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
.CE
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
.CS
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
1113
1114
1115
1116
1117
1118
1119
1120
1121


1122

1123
1124
1125
1126
1127
1128
1129
1088
1089
1090
1091
1092
1093
1094


1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105







-
-
+
+

+







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_schwa                       65162     0xFE8A
dead_SCHWA                       65163     0xFE8B
dead_greek                       65164     0xFE8C
dead_hamza                       65165     0xFE8D
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
1161
1162
1163
1164
1165
1166
1167


1168
1169
1170
1171
1172
1173
1174
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152







+
+







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
.CE
.CS
BackSpace                        65288     0xFF08
Tab                              65289     0xFF09
Linefeed                         65290     0xFF0A
Clear                            65291     0xFF0B
Return                           65293     0xFF0D
Pause                            65299     0xFF13
Scroll_Lock                      65300     0xFF14
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1191
1192
1193
1194
1195
1196
1197


1198
1199
1200
1201
1202
1203
1204







-
-







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
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
1300
1301
1302
1303
1304
1305
1306

1307


































































































































































































































































































































































1308


































































































































































































































































































































































1309
1310
1311
1312
1313
1314
1315







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







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
.CE
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
.CS
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
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












+
+







SunAudioLowerVolume          268828535     0x1005FF77
SunAudioMute                 268828536     0x1005FF78
SunAudioRaiseVolume          268828537     0x1005FF79
SunVideoDegauss              268828538     0x1005FF7A
SunVideoLowerBrightness      268828539     0x1005FF7B
SunVideoRaiseBrightness      268828540     0x1005FF7C
SunPowerSwitchShift          268828541     0x1005FF7D
XF86BrightnessAuto           268964084     0x100810F4
XF86DisplayOff               268964085     0x100810F5
XF86Info                     268964198     0x10081166
XF86AspectRatio              268964215     0x10081177
XF86DVD                      268964229     0x10081185
XF86Audio                    268964232     0x10081188
XF86ChannelUp                268964242     0x10081192
XF86ChannelDown              268964243     0x10081193
XF86Break                    268964251     0x1008119B
XF86VideoPhone               268964256     0x100811A0
XF86ZoomReset                268964260     0x100811A4
XF86Editor                   268964262     0x100811A6
XF86GraphicsEditor           268964264     0x100811A8
XF86Presentation             268964265     0x100811A9
XF86Database                 268964266     0x100811AA
XF86Voicemail                268964268     0x100811AC
XF86Addressbook              268964269     0x100811AD
XF86DisplayToggle            268964271     0x100811AF
XF86SpellCheck               268964272     0x100811B0
XF86ContextMenu              268964278     0x100811B6
XF86MediaRepeat              268964279     0x100811B7
XF8610ChannelsUp             268964280     0x100811B8
XF8610ChannelsDown           268964281     0x100811B9
XF86Images                   268964282     0x100811BA
XF86NotificationCenter       268964284     0x100811BC
XF86PickupPhone              268964285     0x100811BD
XF86HangupPhone              268964286     0x100811BE
XF86Fn                       268964304     0x100811D0
XF86Fn_Esc                   268964305     0x100811D1
XF86FnRightShift             268964325     0x100811E5
XF86Numeric0                 268964352     0x10081200
XF86Numeric1                 268964353     0x10081201
XF86Numeric2                 268964354     0x10081202
XF86Numeric3                 268964355     0x10081203
XF86Numeric4                 268964356     0x10081204
XF86Numeric5                 268964357     0x10081205
XF86Numeric6                 268964358     0x10081206
XF86Numeric7                 268964359     0x10081207
XF86Numeric8                 268964360     0x10081208
XF86Numeric9                 268964361     0x10081209
XF86NumericStar              268964362     0x1008120A
XF86NumericPound             268964363     0x1008120B
XF86NumericA                 268964364     0x1008120C
XF86NumericB                 268964365     0x1008120D
XF86NumericC                 268964366     0x1008120E
XF86NumericD                 268964367     0x1008120F
XF86CameraFocus              268964368     0x10081210
XF86WPSButton                268964369     0x10081211
XF86CameraZoomIn             268964373     0x10081215
XF86CameraZoomOut            268964374     0x10081216
XF86CameraUp                 268964375     0x10081217
XF86CameraDown               268964376     0x10081218
XF86CameraLeft               268964377     0x10081219
XF86CameraRight              268964378     0x1008121A
XF86AttendantOn              268964379     0x1008121B
XF86AttendantOff             268964380     0x1008121C
XF86AttendantToggle          268964381     0x1008121D
XF86LightsToggle             268964382     0x1008121E
XF86ALSToggle                268964400     0x10081230
XF86Buttonconfig             268964416     0x10081240
XF86Taskmanager              268964417     0x10081241
XF86Journal                  268964418     0x10081242
XF86ControlPanel             268964419     0x10081243
XF86AppSelect                268964420     0x10081244
XF86Screensaver              268964421     0x10081245
XF86VoiceCommand             268964422     0x10081246
XF86Assistant                268964423     0x10081247
XF86EmojiPicker              268964425     0x10081249
XF86Dictate                  268964426     0x1008124A
XF86BrightnessMin            268964432     0x10081250
XF86BrightnessMax            268964433     0x10081251
XF86KbdInputAssistPrev       268964448     0x10081260
XF86KbdInputAssistNext       268964449     0x10081261
XF86KbdInputAssistPrevgroup  268964450     0x10081262
XF86KbdInputAssistNextgroup  268964451     0x10081263
XF86KbdInputAssistAccept     268964452     0x10081264
XF86KbdInputAssistCancel     268964453     0x10081265
XF86RightUp                  268964454     0x10081266
XF86RightDown                268964455     0x10081267
XF86LeftUp                   268964456     0x10081268
XF86LeftDown                 268964457     0x10081269
XF86RootMenu                 268964458     0x1008126A
XF86MediaTopMenu             268964459     0x1008126B
XF86Numeric11                268964460     0x1008126C
XF86Numeric12                268964461     0x1008126D
XF86AudioDesc                268964462     0x1008126E
XF863DMode                   268964463     0x1008126F
XF86NextFavorite             268964464     0x10081270
XF86StopRecord               268964465     0x10081271
XF86PauseRecord              268964466     0x10081272
XF86VOD                      268964467     0x10081273
XF86Unmute                   268964468     0x10081274
XF86FastReverse              268964469     0x10081275
XF86SlowReverse              268964470     0x10081276
XF86Data                     268964471     0x10081277
XF86OnScreenKeyboard         268964472     0x10081278
XF86PrivacyScreenToggle      268964473     0x10081279
XF86SelectiveScreenshot      268964474     0x1008127A
XF86Macro1                   268964496     0x10081290
XF86Macro2                   268964497     0x10081291
XF86Macro3                   268964498     0x10081292
XF86Macro4                   268964499     0x10081293
XF86Macro5                   268964500     0x10081294
XF86Macro6                   268964501     0x10081295
XF86Macro7                   268964502     0x10081296
XF86Macro8                   268964503     0x10081297
XF86Macro9                   268964504     0x10081298
XF86Macro10                  268964505     0x10081299
XF86Macro11                  268964506     0x1008129A
XF86Macro12                  268964507     0x1008129B
XF86Macro13                  268964508     0x1008129C
XF86Macro14                  268964509     0x1008129D
XF86Macro15                  268964510     0x1008129E
XF86Macro16                  268964511     0x1008129F
XF86Macro17                  268964512     0x100812A0
XF86Macro18                  268964513     0x100812A1
XF86Macro19                  268964514     0x100812A2
XF86Macro20                  268964515     0x100812A3
XF86Macro21                  268964516     0x100812A4
XF86Macro22                  268964517     0x100812A5
XF86Macro23                  268964518     0x100812A6
XF86Macro24                  268964519     0x100812A7
XF86Macro25                  268964520     0x100812A8
XF86Macro26                  268964521     0x100812A9
XF86Macro27                  268964522     0x100812AA
XF86Macro28                  268964523     0x100812AB
XF86Macro29                  268964524     0x100812AC
XF86Macro30                  268964525     0x100812AD
XF86MacroRecordStart         268964528     0x100812B0
XF86MacroRecordStop          268964529     0x100812B1
XF86MacroPresetCycle         268964530     0x100812B2
XF86MacroPreset1             268964531     0x100812B3
XF86MacroPreset2             268964532     0x100812B4
XF86MacroPreset3             268964533     0x100812B5
XF86KbdLcdMenu1              268964536     0x100812B8
XF86KbdLcdMenu2              268964537     0x100812B9
XF86KbdLcdMenu3              268964538     0x100812BA
XF86KbdLcdMenu4              268964539     0x100812BB
XF86KbdLcdMenu5              268964540     0x100812BC
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
.CE
.CS
XF86Ungrab                   269024800     0x1008FE20
XF86ClearGrab                269024801     0x1008FE21
XF86Next_VMode               269024802     0x1008FE22
XF86Prev_VMode               269024803     0x1008FE23
XF86LogWindowTree            269024804     0x1008FE24
XF86LogGrabInfo              269024805     0x1008FE25
XF86ModeLock                 269025025     0x1008FF01
2239
2240
2241
2242
2243
2244
2245

2246
2247
2248
2249
2250
2251
2252
2253
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664







+








XF86TouchpadOff              269025201     0x1008FFB1
XF86AudioMicMute             269025202     0x1008FFB2
XF86Keyboard                 269025203     0x1008FFB3
XF86WWAN                     269025204     0x1008FFB4
XF86RFKill                   269025205     0x1008FFB5
XF86AudioPreset              269025206     0x1008FFB6
XF86RotationLockToggle       269025207     0x1008FFB7
XF86FullScreen               269025208     0x1008FFB8
.CE
.SH "SEE ALSO"
bind(n), event(n)
.SH KEYWORDS
bind, binding, event, keysym
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/label.n.
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85







-
+







.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?
\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
Changes to doc/labelframe.n.
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+







.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?
\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
Changes to doc/listbox.n.
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
+







.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?
\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
.
379
380
381
382
383
384
385
386

387
388

389


390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
379
380
381
382
383
384
385

386


387
388
389
390

391
392
393
394
395



396
397
398
399
400
401
402







-
+
-
-
+

+
+
-
+




-
-
-







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
\fINumber\fR must be an integer.
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
\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)
If \fIwhat\fR is \fBpages\fR then the view adjusts by
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.
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:
429
430
431
432
433
434
435
436
437



438
439
440
441
442
443
444
445
446
447
448
449
450
427
428
429
430
431
432
433


434
435
436
437
438
439
440


441
442
443
444
445
446
447







-
-
+
+
+




-
-







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
\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.
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.
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.
9
10
11
12
13
14
15
16
17



18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43







44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
9
10
11
12
13
14
15


16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65







-
-
+
+
+




-
+














-
-
-
-
-
-
-
+
+
+
+
+
+
+













-
+







.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
\fBmenu\fI pathName \fR?\fIoptions\fR?
\fBtk_menuSetFocus\fI pathName\fR
.fi
.SO
\-activebackground	\-borderwidth	\-foreground
\-activeborderwidth	\-cursor	\-relief
\-activeforeground	\-disabledforeground	\-takefocus
\-background	\-font	\-activerelief
\-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 (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
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.
This option is ignored under Aqua/macOS, 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
This option is ignored under Aqua/macOS, 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
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283







-
+









-
+







(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
the menu are provided by macOS, 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.
are provided by macOS.
.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.
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322

323
324
325
326
327
328

329
330
331
332

333
334
335
336
337
338
339
340
341
342

343
344
345

346
347
348


349
350


351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393

394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425

426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450

451
452
453
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
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315


316

317
318
319


320

321
322
323


324

325


326

327
328
329
330
331
332
333


334



335



336
337


338
339

340
341
342


343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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







-
+








-
-
+
-



-
-
+
-



-
-
+
-

-
-
+
-







-
-
+
-
-
-
+
-
-
-
+
+
-
-
+
+
-



-
-
+
-










+









+










+







+









+















+








+







+













+





+









+












+














+









+







+







+





+








+




-
-
+
+





+




-
+



+









+





+
-
+


+












+






-
+

+





+










+








+





+
-
+


+







+












+






+





+






+






+





+








+










+

















+










+







+







.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?
\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
.IP \fBactive\fR 12
.
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
.IP \fBend\fR 12
.
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
.IP \fBlast\fR 12
.
Same as \fBend\fR.
.TP 12
\fBnone\fR
.IP \fBnone\fR 12
.
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
.IP \fB@\fIx\fB,\fIy\fR 12
.
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.
Indicates the entry that covers the point in the menu's window specified
For example,
.QW \fB@0\fR
indicates the top-most entry in the window.
by \fIx\fR and \fIy\fR (in pixel coordinates).
If no entry covers that point, then this form is equivalent to \fBnone\fR.
.TP 12
\fInumber\fR
If only a single number is specified, it is treated as the y-coordinate.
.IP \fInumber\fR 12
.
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
.IP \fIpattern\fR 12
.
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:
.\" METHOD: activate
.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.
.\" METHOD: add
.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.
.\" METHOD: cget
.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.
.\" METHOD: clone
.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.
.\" METHOD: configure
.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.
.\" METHOD: delete
.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).
.\" METHOD: entrycget
.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.
.\" METHOD: entryconfigure
.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).
.\" METHOD: index
.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the numerical index corresponding to \fIindex\fR, or
\fBnone\fR if \fIindex\fR was specified as \fBnone\fR.
.\" METHOD: insert
.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.
.\" METHOD: invoke
.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.
.\" METHOD: post
.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.
.\" METHOD: postcascade
.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.
.\" METHOD: type
.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.
.\" METHOD: unpost
.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.
.\" METHOD: xposition
.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.
.\" METHOD: yposition
.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.
.\" OPTION: -activebackground
.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
is active. This option is ignored on Aqua/macOS.
If it 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.
.\" OPTION: -activeforeground
.TP
\fB\-activeforeground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is active.
is active.   This option is ignored on Aqua/macOS.
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.
.\" OPTION: -accelerator
.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.
.\" OPTION: -background
.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).
This option is ignored on Aqua/macOS.
If this option is specified as an empty string (the default), then the
If it 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.
.\" OPTION: -bitmap
.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.
.\" OPTION: -columnbreak
.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
This option is ignored on Aqua/macOS, where menus are always a single
column.
.\" OPTION: -command
.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.
.\" OPTION: -compound
.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.
.\" OPTION: -font
.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.
.\" OPTION: -foreground
.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).
This option is ignored on Aqua/macOS.
If this option is specified as an empty string (the default), then the
If it 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.
.\" OPTION: -hidemargin
.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.
.\" OPTION: -image
.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.
.\" OPTION: -indicatoron
.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.
.\" OPTION: -label
.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.
.\" OPTION: -menu
.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.
.\" OPTION: -offvalue
.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.
.\" OPTION: -onvalue
.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.
.\" OPTION: -selectcolor
.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.
.\" OPTION: -selectimage
.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.
.\" OPTION: -state
.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.
.\" OPTION: -underline
.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.
.\" OPTION: -value
.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.
.\" OPTION: -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
Changes to doc/menubar.n.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







.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
\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
Changes to doc/menubutton.n.
8
9
10
11
12
13
14
15

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

28
29
30
31
32
33
34
8
9
10
11
12
13
14

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

27
28
29
30
31
32
33
34







-
+











-
+







.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?
\fBmenubutton\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-disabledforeground	\-padx
\-activeforeground	\-font	\-pady
\-anchor	\-foreground	\-relief
\-background	\-highlightbackground	\-takefocus
\-bitmap	\-highlightcolor	\-text
\-borderwidth	\-highlightthickness	\-textvariable
\-cursor	\-image	\-underline
\-compound	\-justify	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-direction direction Height
.OP \-direction direction Direction
Specifies where the menu is going to be popup up. \fBabove\fR tries to
pop the menu above the menubutton. \fBbelow\fR tries to pop the menu
below the menubutton. \fBleft\fR tries to pop the menu to the left of
the menubutton. \fBright\fR tries to pop the menu to the right of the
menu button. \fBflush\fR pops the menu directly over the menubutton.
In the case of \fBabove\fR or \fBbelow\fR, the direction will be
reversed if the menu would show offscreen.
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+







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.
on macOS.
.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
118
119
120
121
122
123
124

125
126
127
128
129
130
131

132
133
134
135
136
137
138
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140







+







+







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:
.\" METHOD: cget
.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.
.\" METHOD: configure
.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
Changes to doc/message.n.
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116







-
+







.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?
\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 \fIoption\fR
.
Changes to doc/messageBox.n.
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38







-
+







.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.
is only available on macOS.
.TP
\fB\-default\fR \fIname\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
62
63
64
65
66
67
68
69

70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
62
63
64
65
66
67
68

69


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92







-
+
-
-
+














-
+







\fB\-parent\fR \fIwindow\fR
.
Makes \fIwindow\fR the logical parent of the message box. The message
box is displayed on top of its parent window.
.TP
\fB\-title\fR \fItitleString\fR
.
Specifies a string to display as the title of the message box. This option
Specifies a string to display as the title of the message box. The
is ignored on Mac OS X, where platform guidelines forbid the use of a title
on this kind of dialog.
default value is an empty string.
.TP
\fB\-type\fR \fIpredefinedType\fR
.
Arranges for a predefined set of buttons to be displayed. The
following values are possible for \fIpredefinedType\fR:
.RS
.TP 18
\fBabortretryignore\fR
.
Displays three buttons whose symbolic names are \fBabort\fR,
\fBretry\fR and \fBignore\fR.
.TP 18
\fBok\fR
.
Displays one button whose symbolic name is \fBok\fR.
Displays one button whose symbolic name is \fBok\fR. This is the default.
.TP 18
\fBokcancel\fR
.
Displays two buttons whose symbolic names are \fBok\fR and \fBcancel\fR.
.TP 18
\fBretrycancel\fR
.
Changes to doc/options.n.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
54
55
56
57
58
59
60



61
62
63
64
65
66
67







-
-
-







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.
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176







-
+







all the time.
.OP \-insertontime insertOnTime OnTime
Specifies a non-negative integer value indicating the number of
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.
Specifies a non-negative 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,
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
217
218
219
220
221
222
223







224
225
226
227
228
229
230







-
-
-
-
-
-
-







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
Changes to doc/pack.n.
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
125
126
127
128
129
130
131








132
133
134
135
136
137
138







-
-
-
-
-
-
-
-







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"
154
155
156
157
158
159
160
161

162
163
164
165

166
167

168
169


170
171
172
173
174
175
176
146
147
148
149
150
151
152

153
154
155
156
157
158
159

160
161

162
163
164
165
166
167
168
169
170







-
+




+

-
+

-
+
+







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
\fBpack slaves \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.
.VS "TIP 581"
.TP
\fBpack slaves \fIwindow\fR
\fBpack content \fIwindow\fR
.
Synonym for . \fBpack content \fIwindow\fR
Synonym for \fBpack slaves \fIwindow\fR.
.VE "TIP 581"
.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.
Changes to doc/panedwindow.n.
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102







-
+







.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?
\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 \fR?\fIwindow ...\fR? ?\fIoption value ...\fR?
Changes to doc/photo.n.
20
21
22
23
24
25
26
27

28
29
30
31

32
33
34
35
36
37
38
39
40
41
42






43
44
45

46
47


48
49
50
51



52
53
54
55
56
57
58
59
60

61
62
63
64
65

66

67
68
69
70




71
72

73
74
75

76
77
78
79
80
81
82
83
84
85
20
21
22
23
24
25
26

27
28
29
30

31
32
33
34
35
36






37
38
39
40
41
42
43
44
45
46


47
48




49
50
51
52
53
54
55
56
57
58
59

60





61
62
63




64
65
66
67
68

69
70
71

72



73
74
75
76
77
78
79







-
+



-
+





-
-
-
-
-
-
+
+
+
+
+
+



+
-
-
+
+
-
-
-
-
+
+
+








-
+
-
-
-
-
-
+

+
-
-
-
-
+
+
+
+

-
+


-
+
-
-
-







\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 \fBget \fIx y\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 \fBtransparency \fIsubcommand \fR?\fIarg arg ...\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
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
.VS 8.6
PNG,
.VE 8.6
GIF and PPM/PGM
GIF and PPM/PGM formats are supported, but an interface exists to
allow additional image file formats to be added easily.  A photo image
formats are supported, but an interface exists to allow additional
image file formats to be added easily.  A photo image is transparent
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.
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.
Specifies the contents of the image as a string.  The string should
.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
contain 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
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.
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?}
\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 and optional arguments passed to
\fB\-data\fR or \fB\-file\fR option.
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
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132







-
+







.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?
\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
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258

259
260
261
262
263
264





265
266
267
268



269
270

271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297

298
299
300
301
302
303
304
305
306
307

308
309

310
311
312






313
314
315

316
317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
229
230
231
232
233
234
235

236







237
238
239
240
241
242
243
244
245

246
247





248
249
250
251
252




253
254
255
256

257




258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275

276
277
278
279

280




281
282
283
284


285
286
287
288



289
290
291
292
293
294
295
296

297
298

299

300
301
302



303
304
305
306
307
308
309
310



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327

328

329
330
331



332
333
334
335
336
337
338







-
+
-
-
-
-
-
-
-
+








-
+

-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+

-
+
-
-
-
-
+
















-

-
+



-
+
-
-
-
-




-
-
+


+
-
-
-
+
+
+
+
+
+


-
+

-
+
-



-
-
-








-
-
-
+














-
+

-
+
-



-
-
-







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.
Returns image data in the form of a string. The following options
.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:
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?}
\fB\-format\fI format-name\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.
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.
.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
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 (see \fBIMAGE FORMATS\fR below).
format (where \fIrr\fR is a pair of hexadecimal digits for the red
.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.
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
.VS 8.7
.TP
\fIimageName \fBget\fR \fIx y\fR ?\fB-withalpha\fR?
\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. If the \fB-withalpha\fR
red, green and blue components respectively.
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
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
See \fBIMAGE FORMATS\fR below for details on formats for image data.
.VE 8.7
The following options may be specified:
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\fR {\fIformat-name\fR ?\fIoption value ..\fR?}
\fB\-format \fIformat-name\fR
.
Specifies the format of the image data in \fIdata\fR and, optionally,
Specifies the format of the image data in \fIdata\fR.
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
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 ?\fIoption value ..\fR?}
\fB\-format \fIformat-name\fR
.
Specifies the format of the image data in \fIfilename\fR and,
Specifies the format of the image data in \fIfilename\fR.
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
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404

405
406

407
408
409
410

411
412
413

414
415

416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445






446
447
448
449
450
451
452
453
454
455
362
363
364
365
366
367
368

369
370
371
372
373

374

375
376

377




378

379

380
381

382



383



384
385
386
387
388
389
390
391
392
393
394
395
396
397

398
399
400







401
402
403
404
405
406



407
408
409
410
411
412
413







-
+




-

-
+

-
+
-
-
-
-
+
-

-
+

-
+
-
-
-
+
-
-
-














-
+


-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-







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?
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg arg ...\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?
\fIimageName \fBtransparency get \fIx y\fR
.
Returns true if the pixel at (\fIx\fR,\fIy\fR) is fully transparent,
Returns a boolean indicating if the pixel at (\fIx\fR,\fIy\fR) is
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

transparent.
.VS 8.7
.TP
\fIimageName \fBtransparency set \fIx y\fR \fInewVal\fR ?\fB-alpha\fR?
\fIimageName \fBtransparency set \fIx y boolean\fR
.
Change the transparency of the pixel at (\fIx\fR,\fIy\fR) to
Makes the pixel at (\fIx\fR,\fIy\fR) transparent if \fIboolean\fR is
\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
true, and makes that pixel opaque otherwise.
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?}
\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 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.
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, 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
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
422
423
424
425
426
427
428






429
430











431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452


















453
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







-
-
-
-
-
-
+

-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



-
-
+
+
-
-
-
-
+
-

-
-
-
-
-
-
-
-
-
-
-


-
-
-
-
-
+
+
+
+



-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







.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.
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 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
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.
.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
Some image formats support sub-options, which are specified at the time that
the image is loaded using additional words in the \fB\-format\fR option. At
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:
the time of writing, the following are supported:
.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.
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.
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
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
530
531
532
533
534
535
536

















537
538
539
540
541
542
543







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







.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:
Changes to doc/place.n.
187
188
189
190
191
192
193
194

195
196

197
198

199
200


201
202
203
204
205
206
207
187
188
189
190
191
192
193

194
195
196
197
198

199
200

201
202
203
204
205
206
207
208
209







-
+


+

-
+

-
+
+







.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
\fBplace slaves \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.
.VS "TIP 581"
.TP
\fBplace slaves \fIwindow\fR
\fBplace content \fIwindow\fR
.
Synonym for . \fBplace content \fIwindow\fR
Synonym for \fBplace slaves \fIwindow\fR.
.VE "TIP 581"
.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"
Changes to doc/popup.n.
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-
+







$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}
bind .l <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
Changes to doc/radiobutton.n.
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186







-
+







.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?
\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
.
Changes to doc/scale.n.
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148







-
+







.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?
\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
.
Changes to doc/scrollbar.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\fBscrollbar\fI pathName \fR?\fIoptions\fR?
.SO
\-activebackground	\-highlightcolor	\-repeatdelay
\-background	\-highlightthickness	\-repeatinterval
\-borderwidth	\-jump	\-takefocus
\-cursor	\-orient	\-troughcolor
\-highlightbackground	\-relief
.SE
77
78
79
80
81
82
83
84
85

86
87
88

89
90
91

92
93
94

95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
166
167
168
169

170
171
172
173
174

175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
77
78
79
80
81
82
83


84
85


86
87


88
89


90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192







-
-
+

-
-
+

-
-
+

-
-
+

-
-
+













+













+







+















+












+












+





+








+







Scrollbars can be used to adjust the view in the associated window
by clicking or dragging with the mouse.  See the \fBBINDINGS\fR section
below for details.
.SH "ELEMENTS"
.PP
A scrollbar displays five elements, which are referred to in the
widget commands for the scrollbar:
.TP 10
\fBarrow1\fR
.IP \fBarrow1\fR 10
The top or left arrow in the scrollbar.
.TP 10
\fBtrough1\fR
.IP \fBtrough1\fR 10
The region between the slider and \fBarrow1\fR.
.TP 10
\fBslider\fR
.IP \fBslider\fR 10
The rectangle that indicates what is visible in the associated widget.
.TP 10
\fBtrough2\fR
.IP \fBtrough2\fR 10
The region between the slider and \fBarrow2\fR.
.TP 10
\fBarrow2\fR
.IP \fBarrow2\fR 10
The bottom or right arrow in the scrollbar.
.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:
.\" METHOD: activate
.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.
.\" METHOD: cget
.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.
.\" METHOD: configure
.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.
.\" METHOD: delta
.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.
.\" METHOD: fraction
.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.
.\" METHOD: get
.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.
.\" METHOD: identify
.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.
.\" METHOD: set
.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.
199
200
201
202
203
204
205
206


207
208
209
210
211
212
213
214
215
216










217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240












241
242
243
244
245
246
247







-
+
+










+
+
+
+
+
+
+
+
+
+









-
+
-
-
-
-
-
-
-
-
-
-
-
-







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 .
.QW "\fB.t yview\fR" .
.\" METHOD: moveto
.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.
.\" METHOD: scroll
.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. Fractional number are rounded away from 0, so
become visible.
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
344
345
346
347
348
349
350
351
352
353
354
355





356
357
358

359
360
361
362
363
346
347
348
349
350
351
352





353
354
355
356
357
358
359

360
361
362
363
364
365







-
-
-
-
-
+
+
+
+
+


-
+





.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
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)
ttk::scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/selection.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\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
Changes to doc/send.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\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
Changes to doc/spinbox.n.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
19
20
21
22
23
24
25

26
27
28
29
30
31
32







-







\-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.
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
50
51
52
53
54
55
56

57

58
59
60
61
62
63
64







-
+
-







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
contents.  This value must be less than the \fB\-to\fR option.
\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
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
79
80
81
82
83
84
85

86

87
88
89
90
91
92
93







-
+
-







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
its contents.  This value must be greater than the \fB\-from\fR option.
\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
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+







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?
\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
466
467
468
469
470
471
472
473

474
475

476


477
478


479
480
481
482
483
484
485
486
487
488
489
463
464
465
466
467
468
469

470


471
472
473
474


475
476
477
478


479
480
481
482
483
484
485







-
+
-
-
+

+
+
-
-
+
+


-
-







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
\fINumber\fR must be an integer.
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
\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
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
\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
Changes to doc/text.n.
225
226
227
228
229
230
231
232


233
234
235
236
237
238
239
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240







-
+
+







.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.
Indicates the character just after the mark whose name is \fImark\fR (see
\fBMARKS\fR for details).
.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
843
844
845
846
847
848
849



850
851
852
853
854
855
856
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860







+
+
+







.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.
It might also be generated when selection is affected but not actually changed.
Further, multiple selection changes could happen before events can be processed
leading to multiple events with the same visible selection.
.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
1048
1049
1050
1051
1052
1053
1054
1055

1056
1057
1058
1059
1060
1061
1062
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066







-
+







.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?
\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
.
1277
1278
1279
1280
1281
1282
1283
1284

1285
1286
1287
1288
1289
1290
1291
1281
1282
1283
1284
1285
1286
1287

1288
1289
1290
1291
1292
1293
1294
1295







-
+







.
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?
\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
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
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







-
+
-
-
+












-
+
-
-
-
+
+







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
no other edits were done since then. Generates an error when the redo stack is
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.
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
Undoes the last edit action when the \fB\-undo\fR option is true. An edit
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
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
1345
1346
1347
1348
1349
1350
1351
1352

1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1347
1348
1349
1350
1351
1352
1353

1354
1355
1356

1357
1358
1359
1360
1361
1362
1363
1364







-
+


-
+







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?
\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
command depends on the \fIoption\fR argument that follows the \fBimage\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
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420
1421
1422
1423
1424
1412
1413
1414
1415
1416
1417
1418

1419
1420
1421
1422
1423
1424
1425
1426







-
+







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?
\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?
1690
1691
1692
1693
1694
1695
1696
1697

1698
1699
1700
1701
1702
1703
1704
1692
1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704
1705
1706







-
+







\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?
\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?
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738




1739
1740
1741
1742
1743
1744
1745



1746
1747
1748
1749
1750
1751
1752
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







-
-
-
+
+
+
+





-
-
+
+
+







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
mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButtonPress\fR,
\fBMotion\fR, and \fBKeyPress\fR) or virtual events. Mouse and keyboard event
bindings for a text widget respectively use the \fBcurrent\fR and \fBinsert\fR
marks 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
and \fBLeave\fR events for windows. Mouse events are directed to the current
character, while keyboard events are directed to the insert 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
1857
1858
1859
1860
1861
1862
1863
1864

1865
1866
1867
1868
1869
1870
1871
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872
1873
1874
1875







-
+







\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?
\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 \fIindex option\fR
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
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







-
-
-
-
+
+
+
+




-
+
-
-
-
+
+
+







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
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBunits\fR, \fBpages\fR or
\fBpixels\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 \fBpages\fR then the view adjusts by
pixels are assumed). If \fIwhat\fR is \fBunits\fR, the view adjusts left or
\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
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 \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
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984




1985
1986
1987
1988
1989
1990
1991
1978
1979
1980
1981
1982
1983
1984




1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995







-
-
-
-
+
+
+
+







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
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBunits\fR, \fBpages\fR or
\fBpixels\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
2029
2030
2031
2032
2033
2034
2035
2036

2037
2038
2039
2040
2041
2042
2043
2033
2034
2035
2036
2037
2038
2039

2040
2041
2042
2043
2044
2045
2046
2047







-
+







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
Clicking mouse button 1 positions the insertion cursor at the closest edge of 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
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166



2167
2168
2169
2170
2171
2172
2173
2159
2160
2161
2162
2163
2164
2165



2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177







-
-
-


+
+
+







.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 [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
Changes to doc/tk.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







-
+










+







.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?
\fBtk\fI option \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.
The command can take any of a number of different forms
depending on the \fIoption\fR argument.  The legal forms are:
.\" METHOD: appname
.TP
\fBtk appname \fR?\fInewName\fR?
.
If \fInewName\fR is not specified, this command returns the name
of the application (the name that may be used in \fBsend\fR
commands to communicate with the application).
If \fInewName\fR is specified, then the name of the application
40
41
42
43
44
45
46

47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85

86
87

88
89
90
91
92
93
94
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101







+







+












+


















+


+


+







\fInewName\fR should not start with a capital letter.
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.
.\" METHOD: busy
.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.
.\" METHOD: caret
.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.
.\" METHOD: inactive
.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
.\" METHOD: fontchooser
.TP
\fBtk fontchooser \fIsubcommand\fR ...
.
Controls the Tk font selection dialog. For more details see the
\fBfontchooser\fR manual page.
.\" METHOD: scaling
.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
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128

129
130
131
132
133
134
135
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144







+










+





-
+







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
.\" METHOD: useinputmethods
.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.
.\" METHOD: windowingsystem
.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).
or \fBaqua\fR (macOS Aqua).
.SH "SEE ALSO"
busy(n), fontchooser(n), send(n), winfo(n)
.SH KEYWORDS
application name, send
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/tk4.0.ps.
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
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
/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
34
35
36
37
38
39
40

41
42
43
44




45
46
47
48
49
50
51
52



53
54
55
56
57
58
59
60





61
62
63
64
65
66


67
68
69
70
71
72
73
74
75
76
77
78

79
80
81



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96


97
98
99
100
101
102
103
104
105
106
107
108
109



110
111
112
113


114
115
116
117
118


119
120
121
122
123


124
125
126
127
128
129
130


131
132
133

134
135

136
137


138
139
140





141
142
143
144
145
146


147
148
149
150
151


152
153
154
155
156



157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174







175
176
177
178
179
180
181
182


183
184
185
186
187

188
189

190
191
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
/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
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 {
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
			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
		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
	} def 
/FMLOCAL {
	FrameDict begin
	0 def
	end
	} def
	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
/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
	setpapername 
	manualfeed {true} {papersize} ifelse 
	{manualpapersize} {false} ifelse 
	{desperatepapersize} if
	end
	} def
	end 
	} def 
	/pagesave FMLOCAL
	/orgmatrix FMLOCAL
	/landscape FMLOCAL
/FMBEGINPAGE {
	FrameDict begin
/FMBEGINPAGE { 
	FrameDict begin 
	/pagesave save def
	3.86 setmiterlimit
	/landscape exch 0 ne def
	landscape {
		90 rotate 0 exch neg translate pop
	landscape { 
		90 rotate 0 exch neg translate pop 
		}
		{pop pop}
		ifelse
	xscale yscale scale
	/orgmatrix matrix def
	gsave
	} def
	gsave 
	} def 
/FMENDPAGE {
	grestore
	grestore 
	pagesave restore
	end
	end 
	showpage
	} def
/FMFONTDEFINE {
	} def 
/FMFONTDEFINE { 
	FrameDict begin
	findfont
	ReEncode
	1 index exch
	definefont
	FMfonts 3 1 roll
	findfont 
	ReEncode 
	1 index exch 
	definefont 
	FMfonts 3 1 roll 
	put
	end
	} def
	end 
	} def 
/FMFILLS {
	FrameDict begin
	array /fillvals exch def
	end
	} def
	end 
	} def 
/FMFILL {
	FrameDict begin
	 fillvals 3 1 roll put
	end
	} def
/FMNORMALIZEGRAPHICS {
	end 
	} def 
/FMNORMALIZEGRAPHICS { 
	newpath
	0.0 0.0 moveto
	1 setlinewidth
	0 setlinecap
	0 0 0 sethsbcolor
	0 setgray
	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
/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
	fw urx llx sub div fh ury lly sub div scale 
	llx neg lly neg translate 
	} bind def
/FMENDEPSF {
	FMEPSF restore
	FrameDict begin
	FrameDict begin 
	} bind def
FrameDict begin
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
/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
/setpapername { 
	/papersizedict 14 dict def 
	papersizedict begin
	/papername /unknown def
	/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
233
234
235
236
237
238
239



240
241
242
243
244
245
246
247
248
249
250
251
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
	/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
	stopped 
	} def
/desperatepapersize {
	statusdict /setpageparams known
		{
		paperwidth paperheight 0 1
		paperwidth paperheight 0 1 
		statusdict begin
		{setpageparams} stopped pop
		{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
310
311
312
313
314
315
316




317
318
319
320
321







322
323
324
325
326
327
328
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
/ReEncode { 
	dup 
	length 
	dict begin 
	{
	1 index /FID ne
		{def}
		{pop pop} ifelse
	} forall
	0 eq {/Encoding DiacriticEncoding def} if
	currentdict
	end
	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
	 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
366
367
368
369
370
371
372


373
374
375
376
377
378
379

380
381
382
383
384
385
386
387
388
389


390
391
392

393
394

395
396

397
398

399
400

401
402
403
404

405
406
407


408
409
410
411

412
413
414
415

416
417

418
419

420
421

422
423

424
425
426

427
428
429
430
431
432
433
434
435
436
437

438
439
440

441
442
443
444
445
446
447

448
449
450

451
452
453
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

FMPrintInColor 
	
	{
	/HUE 0 def
	/SAT 0 def
	/BRIGHT 0 def
	% array of arrays Hue and Sat values for the separations [HUE BRIGHT]
	/Colors
	/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 {
      
	/BEGINBITMAPCOLOR { 
		BITMAPCOLOR} def
	/BEGINBITMAPCOLORc {
	/BEGINBITMAPCOLORc { 
		BITMAPCOLORc} def
	/BEGINBITMAPTRUECOLOR {
	/BEGINBITMAPTRUECOLOR { 
		BITMAPTRUECOLOR } def
	/BEGINBITMAPTRUECOLORc {
	/BEGINBITMAPTRUECOLORc { 
		BITMAPTRUECOLORc } def
	/K {
	/K { 
		Colors exch get dup
		0 get /HUE exch store
		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}
			{HUE SAT BRIGHT sethsbcolor} 
		  ifelse
		} def
	/FMsetgray {
		/SAT exch 1.0 exch sub store
	/FMsetgray { 
		/SAT exch 1.0 exch sub store 
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor}
			{HUE SAT BRIGHT sethsbcolor} 
		  ifelse
		} bind def
	}

	
	{
	/BEGINBITMAPCOLOR {
	/BEGINBITMAPCOLOR { 
		BITMAPGRAY} def
	/BEGINBITMAPCOLORc {
	/BEGINBITMAPCOLORc { 
		BITMAPGRAYc} def
	/BEGINBITMAPTRUECOLOR {
	/BEGINBITMAPTRUECOLOR { 
		BITMAPTRUEGRAY } def
	/BEGINBITMAPTRUECOLORc {
	/BEGINBITMAPTRUECOLORc { 
		BITMAPTRUEGRAYc } def
	/FMsetgray {setgray} bind def
	/K {
	/K { 
		pop
		} def
	}
ifelse
/normalize {
	transform round exch round exch itransform
	} bind def
/dnormalize {
	dtransform round exch round exch idtransform
	} bind def
/lnormalize {
/lnormalize { 
	0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
	} bind def
/H {
/H { 
	lnormalize setlinewidth
	} bind def
/Z {
	setlinecap
	} bind def
	/fillvals FMLOCAL
/X {
/X { 
	fillvals exch get
	dup type /stringtype eq
	{8 1 setpattern}
	{8 1 setpattern} 
	{grayness}
	ifelse
	} bind def
/V {
/V { 
	gsave eofill grestore
	} bind def
/N {
/N { 
	stroke
	} bind def
/M {newpath moveto} bind def
/E {lineto} bind def
/D {curveto} bind def
/O {closepath} bind def
	/n FMLOCAL
/L {
/L { 
 	/n exch def
	newpath
	normalize
	moveto
	moveto 
	2 1 n {pop normalize lineto} for
	} bind def
/Y {
	L
/Y { 
	L 
	closepath
	} bind def
	/x1 FMLOCAL
	/x2 FMLOCAL
	/y1 FMLOCAL
	/y2 FMLOCAL
	/rad FMLOCAL
/R {
/R { 
	/y2 exch def
	/x2 exch def
	/y1 exch def
	/x1 exch def
	x1 y1
	x2 y1
	x2 y2
	x1 y2
	4 Y
	4 Y 
	} bind def
/RR {
/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 {
/C { 
	grestore
	gsave
	R
	R 
	clip
	} bind def
	/FMpointsize FMLOCAL
/F {
/F { 
	FMfonts exch get
	FMpointsize scalefont
	setfont
	} bind def
/Q {
/Q { 
	/FMpointsize exch def
	F
	F 
	} bind def
/T {
/T { 
	moveto show
	} bind def
/RF {
/RF { 
	rotate
	0 ne {-1 1 scale} if
	} bind def
/TF {
/TF { 
	gsave
	moveto
	moveto 
	RF
	show
	grestore
	} bind def
/P {
/P { 
	moveto
	0 32 3 2 roll widthshow
	} bind def
/PF {
/PF { 
	gsave
	moveto
	moveto 
	RF
	0 32 3 2 roll widthshow
	grestore
	} bind def
/S {
/S { 
	moveto
	0 exch ashow
	} bind def
/SF {
/SF { 
	gsave
	moveto
	RF
	0 exch ashow
	grestore
	} bind def
/B {
/B { 
	moveto
	0 32 4 2 roll 0 exch awidthshow
	} bind def
/BF {
/BF { 
	gsave
	moveto
	RF
	0 32 4 2 roll 0 exch awidthshow
	grestore
	} bind def
/G {
/G { 
	gsave
	newpath
	normalize translate 0.0 0.0 moveto
	dnormalize scale
	0.0 0.0 1.0 5 3 roll arc
	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 {
/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
	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
/BEGINPRINTCODE { 
	/FMdicttop countdictstack 1 add def 
	/FMoptop count 4 sub def 
	/FMsaveobject save def
	userdict begin
	/showpage {} def
	FMNORMALIZEGRAPHICS
	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
	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
/gn { 
	0 
	{	46 mul 
		cf read pop 
		32 sub 
		dup 46 lt {exit} if 
		46 sub add 
		} loop
	add
	add 
	} bind def
	/str FMLOCAL
/cfs {
	/str sl string def
	0 1 sl 1 sub {str exch val put} for
	str def
/cfs { 
	/str sl string def 
	0 1 sl 1 sub {str exch val put} for 
	str def 
	} bind def
/ic [
/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
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
/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

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
/wh { 
	/len exch def 
	/pos exch def 
	ws 0 len getinterval im pos len getinterval copy pop
	pos len
	pos len 
	} bind def
/bl {
	/len exch def
	/pos exch def
/bl { 
	/len exch def 
	/pos exch def 
	bs 0 len getinterval im pos len getinterval copy pop
	pos len
	pos len 
	} bind def
/s1 1 string def
/fl {
	/len exch def
	/pos exch 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
	pos len 
	} bind def
/hx {
	3 copy getinterval
	cf exch readhexstring pop pop
/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
/wbytes { 
	dup 
	8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
	} bind def
/BEGINBITMAPBWc {
/BEGINBITMAPBWc { 
	1 {} COMMONBITMAPc
	} bind def
/BEGINBITMAPGRAYc {
/BEGINBITMAPGRAYc { 
	8 {} COMMONBITMAPc
	} bind def
/BEGINBITMAP2BITc {
/BEGINBITMAP2BITc { 
	2 {} COMMONBITMAPc
	} bind def
/COMMONBITMAPc {
/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
	/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 {
/BEGINBITMAPBW { 
	1 {} COMMONBITMAP
	} bind def
/BEGINBITMAPGRAY {
/BEGINBITMAPGRAY { 
	8 {} COMMONBITMAP
	} bind def
/BEGINBITMAP2BIT {
/BEGINBITMAP2BIT { 
	2 {} COMMONBITMAP
	} bind def
/COMMONBITMAP {
/COMMONBITMAP { 
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def
	r
	/bitmapsave save def 
	r                    
	/is w d wbytes string def
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{cf is readhexstring pop} image
	bitmapsave restore
	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
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
	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 {
/BITMAPCOLOR { 
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save 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
	/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 {
/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
	/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]
	/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
	bitmapsave restore 
	grestore
	} bind def
/BITMAPTRUECOLORc {
/BITMAPTRUECOLORc { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save 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]
        
        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
        bitmapsave restore 
        grestore
        } bind def
/BITMAPTRUECOLOR {
/BITMAPTRUECOLOR { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save 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
        /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 {
/BITMAPTRUEGRAYc { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save 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]
        
        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
        bitmapsave restore 
        grestore
        } bind def
/ww FMLOCAL
/r FMLOCAL
/g FMLOCAL
/b FMLOCAL
/i FMLOCAL
/gray {
/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 {
/BITMAPTRUEGRAY { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save 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 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
        bitmapsave restore 
        grestore
        } bind def
/BITMAPGRAY {
/BITMAPGRAY { 
	8 {fakecolorsetup} COMMONBITMAP
	} bind def
/BITMAPGRAYc {
/BITMAPGRAYc { 
	8 {fakecolorsetup} COMMONBITMAPc
	} bind def
/ENDBITMAP {
	} bind def
end
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
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
(<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
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
(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 (<Button-1>) 244.35 544.33 P
-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
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20












-
+







'\"
'\" 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
tk::mac \- Access Mac-Specific Functionality on macOS 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54

55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86

87
88
89
90
91
92
93
31
32
33
34
35
36
37

38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97







-





-
+



+







+







+


















+







+







\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
The Aqua/macOS 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.
.\" COMMAND: DoScriptFile
.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.
.\" COMMAND: DoScriptText
.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.
.\" COMMAND: ShowPreferences
.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
used to wrap a specific own preferences command, which pops up a preferences
window. Something like:
.RS
.PP
.CS
proc ::tk::mac::ShowPreferences {} {
    setPref
}
.CE
.RE
.\" COMMAND: OpenApplication
.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 .
.\" COMMAND: ReopenApplication
.TP
\fB::tk::mac::ReopenApplication\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEReopenApplication,
.QW rapp ,
the Apple Event sent when your application is opened when it is already
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144

145
146
147
148
149

150
151
152
153
154
155

156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182







+


















+








+










+





+






+









+







    } else {
        wm deiconify .
    }
    raise .
}
.CE
.RE
.\" COMMAND: OpenDocument
.TP
\fB::tk::mac::OpenDocument \fIfile...\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEOpenDocuments,
.QW odoc ,
the Apple Event sent when your application is asked to open one or more
documents (e.g., by drag & drop onto the app or by opening a document of a
type associated to the app). The proc should take as arguments paths to the
files to be opened, like so:
.RS
.PP
.CS
proc ::tk::mac::OpenDocument {args} {
    foreach f $args {my_open_document $f}
}
.CE
.RE
.\" COMMAND: PrintDocument
.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.
.\" COMMAND: Quit
.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
quit menu item in the application menu, the quit menu item in the Dock menu,
or during a logout/restart/shutdown etc. If this is not defined, \fBexit\fR is
called instead.
.\" COMMAND: OnHide
.TP
\fB::tk::mac::OnHide\fR
.
If defined, this is called when your application receives a kEventAppHidden
event, e.g. via the hide menu item in the application or Dock menus.
.\" COMMAND: OnShow
.TP
\fB::tk::mac::OnShow\fR
.
If defined, this is called when your application receives a kEventAppShown
event, e.g. via the show all menu item in the application menu, or by clicking
the Dock icon of a hidden application.
.\" COMMAND: ShowHelp
.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).
.\" COMMAND: PerformService
.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
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206


207
208
209
210
211

212
213
214
215
216

217

218
219
220
221
222
223
224








225



226
227
228
229

230
231
232
233
234

235
236
237
238
239

240
241
242
243
244
245

246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216


217
218
219
220
221
222

223


224
225

226
227
228
229
230
231




232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282







+









-
-
+
+




-
+
-
-


-
+

+



-
-
-
-
+
+
+
+
+
+
+
+
-
+
+
+




+





+





+






+








+







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.
.\" COMMAND: LaunchURL
.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.
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
.PP


.SH "ADDITIONAL DIALOGS"
.PP
The Aqua/Mac OS X defines additional dialogs that applications should
Aqua/macOS defines additional dialogs that applications should
support.
.\" COMMAND: standardAboutPanel
.TP
\fB::tk::mac::standardAboutPanel\fR
.
Brings the standard Cocoa about panel to the front, with all its information
filled in from your application bundle files (standard about panel with no
options specified). See Apple Technote TN2179 and the AppKit documentation for
-[NSApplication orderFrontStandardAboutPanelWithOptions:] for details on the
Brings the standard Cocoa about panel to the front with information filled in
from the application bundle files. The panel displays the application icon and
the values associated to the info.plist keys named CFBundleName,
CFBundleShortVersionString, NSAboutPanelOptionVersion and
NSHumanReadableCopyright.  If a file named \fICredits.html\fR or
\fICredits.rtf\fR exists in the bundle's Resources directory then its contents
will be displayed in a scrolling text box at the bottom of the dialog. See the
documentation for -[NSApplication orderFrontStandardAboutPanelWithOptions:]
Info.plist keys and app bundle files used by the about panel.
for more details. A hook is also provided for a custom About dialog.  If a Tcl
proc named tkAboutDialog is defined in the main interpreter then that
procedure will be called instead of opening the standardAboutPanel.
.SH "SYSTEM CONFIGURATION"
.PP
There are a number of additional global configuration options that control the
details of how Tk renders by default.
.\" COMMAND: useCompatibilityMetrics
.TP
\fB::tk::mac::useCompatibilityMetrics \fIboolean\fR
.
Preserves compatibility with older Tk/Aqua metrics; set to \fBfalse\fR for
more native spacing.
.\" COMMAND: CGAntialiasLimit
.TP
\fB::tk::mac::CGAntialiasLimit \fIlimit\fR
.
Sets the antialiasing limit; lines thinner that \fIlimit\fR pixels will not be
antialiased. Integer, set to 0 by default, making all lines be antialiased.
.\" COMMAND: antialiasedtext
.TP
\fB::tk::mac::antialiasedtext \fInumber\fR
.
Sets anti-aliased text.  Controls text antialiasing, possible values for
\fInumber\fR are -1 (default, use system default for text AA), 0 (no text AA),
1 (use text AA).
.\" COMMAND: useThemedToplevel
.TP
\fB::tk::mac::useThemedToplevel \fIboolean\fR
.
Sets toplevel windows to draw with the modern grayish/ pinstripe Mac
background. Equivalent to configuring the toplevel with
.QW "\fB\-background systemWindowHeaderBackground\fR" ,
or to using a \fBttk::frame\fR.
.SH "SUPPORT COMMANDS"
.\" COMMAND: iconBitmap
.TP
\fB::tk::mac::iconBitmap \fIname width height \-kind value\fR
.
Renders native icons and bitmaps in Tk applications (including any image file
readable by NSImage). A native bitmap name is interpreted as follows (in
order):
.RS
268
269
270
271
272
273
274

275
276
277
278

279
280
281
282

283
284
285
286

287
288
289
290

291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334







+




+




+




+




+




+












.IP \(bu 3
NSImage url string
.IP \(bu 3
4-char OSType of IconServices icon
.PP
The \fIwidth\fR and \fIheight\fR arguments to \fBtk::mac::iconBitmap\fR define
the dimensions of the image to create, and \fI\-kind\fR must be one of:
.\" OPTION: -file
.TP
\fB\-file\fR
.
icon of file at given path
.\" OPTION: -fileType
.TP
\fB\-fileType\fR
.
icon of given file type
.\" OPTION: -osType
.TP
\fB\-osType\fR
.
icon of given 4-char OSType file type
.\" OPTION: -systemType
.TP
\fB\-systemType\fR
.
icon for given IconServices 4-char OSType
.\" OPTION: -namedImage
.TP
\fB\-namedImage\fR
.
named NSImage for given name
.\" OPTION: -imageFile
.TP
\fB\-imageFile\fR
.
image at given path
.RE
.SH "SEE ALSO"
bind(n), wm(n)
.SH KEYWORDS
about dialog, antialiasing, Apple event, icon, NSImage
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/tkvars.n.
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36







-
+







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
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,
Changes to doc/toplevel.n.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43



44
45
46
47
48
49
50
21
22
23
24
25
26
27











28
29
30
31

32
33
34
35
36
37
38
39
40
41







-
-
-
-
-
-
-
-
-
-
-




-
+
+
+







.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.
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 \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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
69
70
71
72
73
74
75









76
77
78
79
80
81
82







-
-
-
-
-
-
-
-
-







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
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131







-
+









-
+







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
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:
.PP
.CS
\fIpathName option \fR?\fIarg ...\fR?
\fIpathName option \fR?\fIarg arg ...\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
Changes to doc/ttk_button.n.
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







\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
\-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
Changes to doc/ttk_combobox.n.
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29







-
+







.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
\-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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
146
147
148
149
150
151
152


153
154
155
156
157
158
159







-
-







.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
Changes to doc/ttk_entry.n.
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36







-
+







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
\-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
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
452
453
454
455
456
457
458


459
460
461
462
463
464
465







-
-







.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
Changes to doc/ttk_frame.n.
13
14
15
16
17
18
19
20
21


22
23
24
25
26
27
28
13
14
15
16
17
18
19


20
21
22
23
24
25
26
27
28







-
-
+
+







\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
\-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:
Changes to doc/ttk_image.n.
75
76
77
78
79
80
81



82
83
84
85
86
87
88

89
90
91
92
93
94
95
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







+
+
+






-
+







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).
.PP
An image element that is not meant to claim any space (for example when used
as a background image) should use \fB\-width 0\fR and \fB\-height 0\fR.
.SH "EXAMPLE"
.PP
.CS
set img1 [image create photo \-file button.png]
set img2 [image create photo \-file button-pressed.png]
set img3 [image create photo \-file button-active.png]
style element create Button.button image \e
ttk::style element create Button.button image \e
    [list $img1  pressed $img2  active $img3] \e
    \-border {2 4} \-sticky we
.CE
.SH "SEE ALSO"
ttk::intro(n), ttk::style(n), ttk_vsapi(n), image(n), photo(n)
.SH KEYWORDS
style, theme, appearance, pixmap theme, image
Changes to doc/ttk_intro.n.
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131







-
+







.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 <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
Changes to doc/ttk_label.n.
14
15
16
17
18
19
20
21
22
23
24




25
26
27






28
29
30










31
32
33
34
35
36
37
14
15
16
17
18
19
20




21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52







-
-
-
-
+
+
+
+
-


+
+
+
+
+
+



+
+
+
+
+
+
+
+
+
+







.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
\-class	\-compound	\-cursor
\-image	\-padding	\-state
\-style	\-takefocus	\-text
\-textvariable	\-underline	\-width
\-width	\-wraplength
.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 \-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
Changes to doc/ttk_labelframe.n.
14
15
16
17
18
19
20
21
22


23
24
25
26
27
28
29
14
15
16
17
18
19
20


21
22
23
24
25
26
27
28
29







-
-
+
+







.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
\-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:
Changes to doc/ttk_notebook.n.
228
229
230
231
232
233
234
235









236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251




















252
253
254
255
256
257














258
259
260
261
262
263
264
265
266
267
268
269
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311







-
+
+
+
+
+
+
+
+
+
















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+












.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-tabmargins\fP \fIpadding\fP
.br
\fB\-tabposition\fP \fIside\fP
\fB\-tabposition\fP \fIposition\fP
.RS
Specifies the position of the tab row or column as a string of length
1 or 2.  The first character indicates the side as \fBn\fP, \fBs\fP,
\fBw\fP, or \fBe\fP, while the second character (if present) is the
sticky bit (specified as \fBw\fP, \fBe\fP, \fBn\fP, or \fBs\fP) within
the tab position.  The default position is \fBn\fP for the \fBaqua\fP
theme and \fBnw\fP for all the other built-in themes.
.RE
.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.
For example, the Ttk library file \fBvistaTheme.tcl\fP contains
the lines
.CS
ttk::style configure TNotebook -tabmargins {2 2 2 0}
ttk::style map TNotebook.Tab -expand {selected {2 2 2 2}}
.CE
which are valid for the default value \fBnw\fP of the \fB\-tabposition\fP
style option.  For a \fBttk::notebook\fP style \fBnbStyle\fP defined by
.CS
set nbStyle SW.TNotebook
ttk::style configure $nbStyle -tabposition sw
.CE
you will have to adapt the above settings as follows:
.CS
ttk::style configure $nbStyle -tabmargins {2 0 2 2}
ttk::style map $nbStyle.Tab -expand {selected {2 2 2 2}}
.CE
The easiest way to do this is to invoke the library procedure
\fBttk::configureNotebookStyle\fP with \fB$nbStyle\fP as argument, after
setting the style's \fB\-tabposition\fP option.
.RE
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.RS
Some themes use a different \fIpadding\fP for the selected tab.  For example,
the Ttk library file \fBclamTheme.tcl\fP contains the lines
.CS
ttk::style configure TNotebook.Tab -padding {6 2 6 2}
ttk::style map TNotebook.Tab -padding {selected {6 4 6 2}}
.CE
which are valid for the default value \fBnw\fP of the \fB\-tabposition\fP
style option.  For a \fBttk::notebook\fP style having a different tab position
you will have to adapt the above settings accordingly.  Again, the easiest way
to do this is to invoke the library procedure \fBttk::configureNotebookStyle\fP
with the style name as argument, after setting the style's \fB\-tabposition\fP
option.
.RE
.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:
Changes to doc/ttk_panedwindow.n.
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
113
114
115
116
117
118
119

120


121
122
123
124
125
126
127







-
+
-
-







.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
LeaveNotify/NotifyInferior events.
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:
Changes to doc/ttk_progressbar.n.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


31
32
33
34
35
36

37
38
39
40
41
42
43
44
15
16
17
18
19
20
21






22


23
24

25
26
27
28

29

30
31
32
33
34
35
36







-
-
-
-
-
-

-
-
+
+
-




-
+
-







.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
\-class	\-cursor	\-takefocus
\-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
(width if horizontal, height if vertical).
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.
Changes to doc/ttk_scale.n.
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109







-
+







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
\fBTScale\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
Changes to doc/ttk_scrollbar.n.
114
115
116
117
118
119
120








121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136








137
138
139
140
141
142
143







+
+
+
+
+
+
+
+








-
-
-
-
-
-
-
-







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.
.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.
Changes to doc/ttk_sizegrip.n.
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38







-
+







.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.
.SH "PLATFORM-SPECIFIC NOTES"
.PP
On Mac OSX, toplevel windows automatically include a built-in
On macOS, toplevel windows automatically include a built-in
size grip by default.
Adding a \fBttk::sizegrip\fR there is harmless, since
the built-in grip will just mask the widget.
.SH EXAMPLES
.PP
Using pack:
.CS
Changes to doc/ttk_spinbox.n.
17
18
19
20
21
22
23
24
25


26
27
28
29
30
31
32
17
18
19
20
21
22
23


24
25
26
27
28
29
30
31
32







-
-
+
+







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
\-class	\-cursor	\-state
\-style	\-takefocus	\-xscrollcommand
.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.
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
111
112
113
114
115
116
117


118
119
120
121
122
123
124







-
-







.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
Changes to doc/ttk_treeview.n.
97
98
99
100
101
102
103


104
105
106
107
108
109
110
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112







+
+







Returns the bounding box (relative to the treeview widget's window)
of the specified \fIitem\fR
in the form \fIx y width height\fR.
If \fIcolumn\fR is specified, returns the bounding box of that cell.
If the \fIitem\fR is not visible
(i.e., if it is a descendant of a closed item or is scrolled offscreen),
returns the empty list.
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 \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathname \fBchildren \fIitem\fR ?\fInewchildren\fR?
If \fInewchildren\fR is not specified,
returns the list of children belonging to \fIitem\fR.
207
208
209
210
211
212
213


214
215
216
217
218
219
220
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224







+
+







Use \fIpathname heading #0\fR to configure the tree column heading.
.RE
.TP
\fIpathname \fBidentify \fIcomponent x y\fR
Returns a description of the specified \fIcomponent\fR
under the point given by \fIx\fR and \fIy\fR,
or the empty string if no such \fIcomponent\fR is present at that position.
The values \fIx\fR and \fIy\fR may have any of the forms acceptable to
\fBTk_GetPixels\fR.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify region \fIx y\fR
.RS
Returns one of:
.IP heading
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





395
396
397
398
399
400
401
344
345
346
347
348
349
350





351
352
353
354
355
356
357

358
359

360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378






379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399







-
-
-
-
-







-
+

-
+


















-
-
-
-
-
-









+
+
+
+
+







.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
\fB<KeyPress>\fR, \fB<KeyRelease>\fR, and virtual events
are sent to the focus item.
\fB<Button>\fR, \fB<ButtonRelease>\fR, and \fB<Motion>\fR events
\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 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 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 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
474
475
476
477
478
479
480



481
482
483
484
485
486
487
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488







+
+
+







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.
It might also be generated when selection is affected but not actually changed.
Further, multiple selection changes could happen before events can be processed
leading to multiple events with the same visible selection.
.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.
503
504
505
506
507
508
509






510
511
512


513
514
515






516
517
518
519
520
521
522
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







+
+
+
+
+
+



+
+
-
-
-
+
+
+
+
+
+







\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\-indent\fP \fIamount\fP
.RS
Specifies how far items are indented from their parents. Defaults to 20 pixels.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
.RE
.br
\fB\-rowheight\fP \fIamount\fP
.RS
This is the standard height for an item. Defaults to 20 pixels.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
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.
If \fB\-rowheight\fP is not set by the style, it is set by measuring an
item and a cell layout with the style's settings.
This thus picks up the font and
any focus ring or padding from the theme's layout.
The \fB\-rowheight\fP may need to be set to make sure that a row
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
Changes to doc/ttk_widget.n.
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
67
68
69
70
71
72
73






74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
-
-
-
-
-






-
+







.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:
The other valid values are:
.RS
.IP text
Display text only.
.IP image
Display image only.
.IP center
Display text centered on top of image.
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129


130
131
132
133


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203



204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231
232

233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248


249
250
251
252

253
254
255
256
257

258
259
260

261
262

263
264


265
266
267
268
269
270
271

272
273

274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289


290
291
292
293

294
295
296
297
298

299
300
301
302

303
304


305
306
307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332

333
334
335
336

337
338
339
340
341
342

343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358

359
360
361
362

363
364
365
366
367
368
369
370
371

372
373
374
375
376
377

378
379
380
381
382
383
384


385
386
387
388
389
390
391
102
103
104
105
106
107
108





109
110
111
112
113
114
115
116


117
118
119
120


121
122
123
124
125
126
127
128
129
130
131
132
133
134

















135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244


245
246

247
248
249
250
251
252


253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291

292
293
294
295
296
297


298
299
300
301


302

303
304
305
306
307
308
309


310

311
312
313


314

315


316

317
318
319


320

321
322
323
324
325


326

327
328
329
330
331


332

333


334

335
336
337
338
339
340


341

342
343
344


345

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360







-
-
-
-
-








-
-
+
+


-
-
+
+












-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-












+





+
















+







-
+
+
+










+

















+


+






+









-
+
+




+





+


-
+
-
-
+

-
+
+




-
-

+


+






+









-
+
+




+





+



-
+

-
+
+




-
-




-
-
+
-







-
-
+
-



-
-
+
-

-
-
+
-



-
-
+
-





-
-
+
-





-
-
+
-

-
-
+
-






-
-
+
-



-
-
+
-






+
+







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;
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).
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
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
.\" METHOD: configure
.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.
.\" METHOD: identify
.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.
Some widgets accept other \fBidentify\fR subcommands described
in these widgets documentation.
.\" METHOD: instate
.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
.\" METHOD: state
.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
.\" METHOD: xview
.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
\fIpathName \fBxview\fI index\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
\fINumber\fR must be an integer.
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
\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
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.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE
.\" METHOD: yview
.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
\fIpathName \fByview\fI index\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.
\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
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down 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 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
.IP \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
.IP \fBdisabled\fR
.
Widget is disabled under program control (aka
.QW unavailable ,
.QW inactive ).
.TP
\fBfocus\fR
.IP \fBfocus\fR
.
Widget has keyboard focus.
.TP
\fBpressed\fR
.IP \fBpressed\fR
.
Widget is being pressed (aka
.QW armed
in Motif).
.TP
\fBselected\fR
.IP \fBselected\fR
.
.QW On ,
.QW true ,
or
.QW current
for things like checkbuttons and radiobuttons.
.TP
\fBbackground\fR
.IP \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
.IP \fBreadonly\fR
.
Widget should not allow user modification.
.TP
\fBalternate\fR
.IP \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
.IP \fBinvalid\fR
.
The widget's value is invalid.
(Potential uses: scale widget value out of bounds,
entry widget value failed validation.)
.TP
\fBhover\fR
.IP \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.
.IP \fBuser1\fR-\fBuser3\fR
Freely usable for other purposes
.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]
Changes to doc/winfo.n.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\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
Changes to doc/wish.1.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







.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?
\fBwish\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg 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.
Changes to doc/wm.n.
8
9
10
11
12
13
14
15

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

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67

68
69
70
71
72
73


74
75
76
77
78
79

80
81
82
83

84
85
86
87

88
89
90
91
92
93
94
95
96
97


98
99
100
101
102
103

104
105
106
107

108
109
110
111
112



113
114
115
116
117
118
119
120
121
122
123


124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139

140
141
142
143

144
145
146
147
148

149
150
151
152
153

154
155
156
157
158

159
160
161
162

163
164
165
166
167

168
169
170
171
172

173
174
175
176
177

178
179
180
181
182

183
184
185
186
187
188

189
190
191
192
193

194
195
196
197
198
199

200
201
202
203

204
205
206
207
208

209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121


122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146


147

148


149

150


151

152
153


154

155
156


157

158
159


160

161


162

163
164


165

166
167


168

169
170


171

172
173


174

175
176
177


178

179
180


181

182
183
184


185

186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222







-
+












+

















+
















+







+





-
+
+






+




+




+









-
+
+






+




+



-
-
+
+
+










-
+
+










-
-
+
-

-
-
+
-

-
-
+
-


-
-
+
-


-
-
+
-


-
-
+
-

-
-
+
-


-
-
+
-


-
-
+
-


-
-
+
-


-
-
+
-



-
-
+
-


-
-
+
-



-
-
+
-



+




-
+






+













+







.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
\fBwm\fR \fIoption window \fR?\fIargs\fR?
\fBwm\fI option window \fR?\fIargs\fR?
.BE
.SH DESCRIPTION
.PP
The \fBwm\fR command is used to interact with window managers in
order to control such things as the title for a window, its geometry,
or the increments in terms of which it may be resized.  The \fBwm\fR
command can take any of a number of different forms, depending on
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:
.\" METHOD: aspect
.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).
.\" METHOD: attributes
.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):
.\" OPTION: -alpha
.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.
.\" OPTION: -fullscreen
.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).
Windows, dock and menubar on macOS, general window decorations on X11).
.\" OPTION: -topmost
.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.
.\" OPTION: -disabled
.TP
\fB\-disabled\fR
.
Specifies whether the window is in a disabled state.
.\" OPTION: -toolwindow
.TP
\fB\-toolwindow\fR
.
Specifies a toolwindow style window (as defined in the MSDN).
.\" OPTION: -transparentcolor
.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.
On macOS, the following attributes may be set.
.\" OPTION: -modified
.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).
.\" OPTION: -notify
.TP
\fB\-notify\fR
.
Specifies process notification state (bouncing of the application dock icon).
.\" OPTION: -titlepath
.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).
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).
.\" OPTION: -transparent
.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
.\" See https://www.freedesktop.org/wiki/Specifications/wm-spec/
.\" OPTION: -type
.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
.IP \fBdesktop\fR
.
indicates a desktop feature,
.TP
\fBdock\fR
.IP \fBdock\fR
.
indicates a dock/panel feature,
.TP
\fBtoolbar\fR
.IP \fBtoolbar\fR
.
indicates a toolbar window that should be acting on behalf of another window,
as indicated with \fBwm transient\fR,
.TP
\fBmenu\fR
.IP \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
.IP \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
.IP \fBsplash\fR
.
indicates a splash screen, displayed during application start up,
.TP
\fBdialog\fR
.IP \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
.IP \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
.IP \fBpopup_menu\fR
.
indicates a popup menu, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBtooltip\fR
.IP \fBtooltip\fR
.
indicates a tooltip window, which should usually also be set to be
override-redirected (with \fBwm overrideredirect\fR),
.TP
\fBnotification\fR
.IP \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
.IP \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
.IP \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
.IP \fBnormal\fR
.
indicates a window that has no special interpretation.
.RE
.VE 8.6
.\" OPTION: -zoomed
.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.
zoomed\fR on Windows and macOS.
.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
.\" METHOD: client
.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.
.\" METHOD: colormapwindows
.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
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318







+












+










+




















+








+









+







If \fBwm colormapwindows\fR is not invoked, Tk will automatically set
the property for each top-level window to all the internal windows
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
.\" METHOD: command
.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.
.\" METHOD: deiconify
.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.
.\" METHOD: focusmodel
.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
.\" METHOD: forget
.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.
.\" METHOD: frame
.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.
.\" METHOD: geometry
.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
355
356
357
358
359
360
361

362
363
364
365
366
367
368
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363







+







actual size and location of \fIwindow\fR, whereas \fBwm geometry\fR allows
both setting and querying of the \fIwindow manager\fR's understanding of the
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
.\" METHOD: grid
.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
387
388
389
390
391
392
393
394

395
396
397

398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412







-
+



+











+







.PP
Otherwise the return value is a Tcl list containing
four elements corresponding to the current \fIbaseWidth\fR,
\fIbaseHeight\fR, \fIwidthInc\fR, and \fIheightInc\fR;  if
\fIwindow\fR is not currently gridded, then an empty string
is returned.
.PP
Note: this command should not be needed very often, since the
Note that 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
.\" METHOD: group
.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.
.\" METHOD: iconbitmap
.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
431
432
433
434
435
436
437

438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477







+






+















+











+







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
.\" METHOD: iconify
.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.
.\" METHOD: iconmask
.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.
.\" METHOD: iconname
.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).
.\" METHOD: iconphoto
.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
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
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







-
+







+










+

















-
+
+
+









+















+















+




















+







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
On Macintosh, the first image called is loaded into an OS-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
.\" METHOD: iconposition
.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).
.\" METHOD: iconwindow
.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.
Note that not all window managers support the notion of an icon window, and
the concept is entirely meaningless on non-X11 platforms.
.\" METHOD: manage
.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.
.\" METHOD: maxsize
.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.
.\" METHOD: minsize
.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.
.\" METHOD: overrideredirect
.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
.\" METHOD: positionfrom
.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
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
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







+



-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+


+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
















+


















+














+





-
-
+
+





+









+


















+










-
+







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.
.\" METHOD: protocol
.TP
\fBwm protocol \fIwindow\fR ?\fIname\fR? ?\fIcommand\fR?
.
This command is used to manage window manager protocols such as
This command is used to manage window manager protocols. The \fIname\fR
\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.
\fIName\fR will be added to \fIwindow\fR's \fBWM_PROTOCOLS\fR
property to tell the window manager that the application has a
protocol handler for \fIname\fR, and \fIcommand\fR will
be invoked in the future whenever the window manager sends a
message to the client for that protocol.
In this case the command returns an empty string.
argument in the \fBwm protocol\fR command is the name of an atom corresponding
to a window manager protocol.  Examples include \fBWM_DELETE_WINDOW\fR or
\fBWM_SAVE_YOURSELF\fR or \fBWM_TAKE_FOCUS\fR.
.RS
.PP
A \fIwindow manager protocol\fR is a class of messages sent from a window
manager to a Tk application outside of the normal event processing system. The
main example is the \fBWM_DELETE_WINDOW\fR protocol; these messages are sent
when the user clicks the close widget in the title bar of a window.  Handlers
for window manager protocols are installed with the \fBwm protocol\fR
command. As a rule, if no handler has been installed for a protocol by the
\fBwm protocol\fR command then all messages of that protocol are ignored. The
If \fIname\fR is specified but \fIcommand\fR is not, then the current
command for \fIname\fR is returned, or an empty string if there
is no handler defined for \fIname\fR.
If \fIcommand\fR is specified as an empty string then the current
handler for \fIname\fR is deleted and it is removed from the
\fBWM_PROTOCOLS\fR property on \fIwindow\fR;  an empty string is
returned.
\fBWM_DELETE_WINDOW\fR protocol is an exception to this rule. At start-up Tk
installs a handler for this protocol, which responds by destroying the
window. The \fBwm protocol\fR command can be used to replace this default
handler by one which responds differently.
.RE
.RS
Lastly, if neither \fIname\fR nor \fIcommand\fR is specified, the
command returns a list of all the protocols for which handlers
are currently defined for \fIwindow\fR.
.PP
The list of available window manager protocols depends on the window manager,
but all window managers supported by Tk provide \fBWM_DELETE_WINDOW\fR. On the
Windows platform, a \fBWM_SAVE_YOURSELF\fR message is sent on user logout
or system restart.
.RE
.RS
.PP
If both \fIname\fR and \fIcommand\fR are specified, then \fIcommand\fR becomes
Tk always defines a protocol handler for \fBWM_DELETE_WINDOW\fR, even if
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.
the handler for the protocol specified by \fIname\fR. The atom for \fIname\fR
will be added to \fIwindow\fR's \fBWM_PROTOCOLS\fR property to tell the window
manager that the application has a handler for the protocol specified by
\fIname\fR, and \fIcommand\fR will be invoked in the future whenever the
window manager sends a message of that protocol to the Tk application.  In
this case the \fBwm protocol\fR command returns an empty string.  If
\fIname\fR is specified but \fIcommand\fR is not, then the current handler for
\fIname\fR is returned, or an empty string if there is no handler defined for
\fIname\fR (as a special case, the default handler for \fBWM_DELETE_WINDOW\fR
is not returned).  If \fIcommand\fR is specified as an empty string then the
atom for \fIname\fR is removed from the \fBWM_PROTOCOLS\fR property of
\fIwindow\fR and the handler is destroyed; an empty string is returned.
Lastly, if neither \fIname\fR nor \fIcommand\fR is specified, the
\fBwm protocol\fR command returns a list of all of the protocols for which
handlers are currently defined for \fIwindow\fR.
.RE
.\" METHOD: resizable
.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.
.\" METHOD: sizefrom
.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.
.\" METHOD: stackorder
.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.
.\" METHOD: state
.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.
\fBnormal\fR, \fBiconic\fR, \fBwithdrawn\fR, \fBicon\fR, or (Windows and macOS
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.
.\" METHOD: title
.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.
.\" METHOD: transient
.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.
.\" METHOD: widthdraw
.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.
Note: it sometimes seems to be necessary to withdraw a
Note that it sometimes seems to be necessary to withdraw a
window and then re-map it (e.g. with \fBwm deiconify\fR) to get some
window managers to pay attention to changes in window attributes
such as group.
.SH "GEOMETRY MANAGEMENT"
.PP
By default a top-level window appears on the screen in its
\fInatural size\fR, which is the one determined internally by its
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
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







-
-
-
-
+
+
+
+








-
-
+
+








-
+
+



\fBwm resizable\fR .fixed 0 0
.CE
.PP
A simple dialog-like window, centred on the screen:
.CS
# Create and arrange the dialog contents.
toplevel .msg
label  .msg.l  \-text "This is a very simple dialog demo."
button .msg.ok \-text OK \-default active \-command {destroy .msg}
pack .msg.ok \-side bottom \-fill x
pack .msg.l  \-expand 1    \-fill both
label  .msg.l  -text "This is a very simple dialog demo."
button .msg.ok -text OK -default active -command {destroy .msg}
pack .msg.ok -side bottom -fill x
pack .msg.l  -expand 1    -fill both

# Now set the widget up as a centred dialog.

# But first, we need the geometry managers to finish setting
# up the interior of the dialog, for which we need to run the
# event loop with the widget hidden completely...
\fBwm withdraw\fR .msg
update
set x [expr {([winfo screenwidth .]\-[winfo width .msg])/2}]
set y [expr {([winfo screenheight .]\-[winfo height .msg])/2}]
set x [expr {([winfo screenwidth .] - [winfo width .msg]) / 2}]
set y [expr {([winfo screenheight .] - [winfo height .msg]) / 2}]
\fBwm geometry\fR  .msg +$x+$y
\fBwm transient\fR .msg .
\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
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:
Changes to generic/ks_names.h.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45






46
47
48









49
50
51
52
53
54
55
16
17
18
19
20
21
22

23




24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62







-

-
-
-
-

















+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+







{ "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 },
{ "Hangul", 0xFF31 },
{ "Hangul_Start", 0xFF32 },
{ "Hangul_End", 0xFF33 },
{ "Hangul_Hanja", 0xFF34 },
{ "Hangul_Jamo", 0xFF35 },
{ "Hangul_Romaja", 0xFF36 },
{ "Kanji_Bangou", 0xFF37 },
{ "Zen_Koho", 0xFF3D },
{ "Mae_Koho", 0xFF3E },
{ "Codeinput", 0xFF37 },
{ "Hangul_Jeonja", 0xFF38 },
{ "Hangul_Banja", 0xFF39 },
{ "Hangul_PreHanja", 0xFF3A },
{ "Hangul_PostHanja", 0xFF3B },
{ "SingleCandidate", 0xFF3C },
{ "MultipleCandidate", 0xFF3D },
{ "PreviousCandidate", 0xFF3E },
{ "Hangul_Special", 0xFF3F },
{ "Home", 0xFF50 },
{ "Left", 0xFF51 },
{ "Up", 0xFF52 },
{ "Right", 0xFF53 },
{ "Down", 0xFF54 },
{ "Prior", 0xFF55 },
{ "Page_Up", 0xFF55 },
69
70
71
72
73
74
75




76
77
78
79
80
81
82
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93







+
+
+
+







{ "Menu", 0xFF67 },
{ "Find", 0xFF68 },
{ "Cancel", 0xFF69 },
{ "Help", 0xFF6A },
{ "Break", 0xFF6B },
{ "Mode_switch", 0xFF7E },
{ "script_switch", 0xFF7E },
{ "kana_switch", 0xFF7E },
{ "Arabic_switch", 0xFF7E },
{ "Greek_switch", 0xFF7E },
{ "Hebrew_switch", 0xFF7E },
{ "Num_Lock", 0xFF7F },
{ "KP_Space", 0xFF80 },
{ "KP_Tab", 0xFF89 },
{ "KP_Enter", 0xFF8D },
{ "KP_F1", 0xFF91 },
{ "KP_F2", 0xFF92 },
{ "KP_F3", 0xFF93 },
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131







-
















+







{ "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 },
{ "KP_0", 0xFFB0 },
{ "KP_1", 0xFFB1 },
{ "KP_2", 0xFFB2 },
{ "KP_3", 0xFFB3 },
{ "KP_4", 0xFFB4 },
{ "KP_5", 0xFFB5 },
{ "KP_6", 0xFFB6 },
{ "KP_7", 0xFFB7 },
{ "KP_8", 0xFFB8 },
{ "KP_9", 0xFFB9 },
{ "KP_Equal", 0xFFBD },
{ "F1", 0xFFBE },
{ "F2", 0xFFBF },
{ "F3", 0xFFC0 },
{ "F4", 0xFFC1 },
{ "F5", 0xFFC2 },
{ "F6", 0xFFC3 },
{ "F7", 0xFFC4 },
181
182
183
184
185
186
187











188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206



207
208
209
210
211
212
213
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235







+
+
+
+
+
+
+
+
+
+
+





-
-
-











+
+
+







{ "Meta_R", 0xFFE8 },
{ "Alt_L", 0xFFE9 },
{ "Alt_R", 0xFFEA },
{ "Super_L", 0xFFEB },
{ "Super_R", 0xFFEC },
{ "Hyper_L", 0xFFED },
{ "Hyper_R", 0xFFEE },
{ "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 },
{ "Delete", 0xFFFF },
{ "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_Level5_Shift", 0xFE11 },
{ "ISO_Level5_Latch", 0xFE12 },
{ "ISO_Level5_Lock", 0xFE13 },
{ "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 },
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295































296
297
298
299
300
301
302
278
279
280
281
282
283
284






















285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







{ "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 },
{ "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_schwa", 0xFE8A },
{ "dead_small_schwa", 0xFE8A },
{ "dead_SCHWA", 0xFE8B },
{ "dead_capital_schwa", 0xFE8B },
{ "dead_greek", 0xFE8C },
{ "dead_hamza", 0xFE8D },
{ "dead_lowline", 0xFE90 },
{ "dead_aboveverticalline", 0xFE91 },
{ "dead_belowverticalline", 0xFE92 },
{ "dead_longsolidusoverlay", 0xFE93 },
{ "ch", 0xFEA0 },
{ "Ch", 0xFEA1 },
{ "CH", 0xFEA2 },
{ "c_h", 0xFEA3 },
{ "C_h", 0xFEA4 },
{ "C_H", 0xFEA5 },
{ "First_Virtual_Screen", 0xFED0 },
{ "Prev_Virtual_Screen", 0xFED1 },
{ "Next_Virtual_Screen", 0xFED2 },
{ "Last_Virtual_Screen", 0xFED4 },
{ "Terminate_Server", 0xFED5 },
{ "Pointer_Left", 0xFEE0 },
{ "Pointer_Right", 0xFEE1 },
{ "Pointer_Up", 0xFEE2 },
{ "Pointer_Down", 0xFEE3 },
{ "Pointer_UpLeft", 0xFEE4 },
{ "Pointer_UpRight", 0xFEE5 },
{ "Pointer_DownLeft", 0xFEE6 },
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
345
346
347
348
349
350
351

352
353
354
355

356



































357
358
359
360
361
362
363







-




-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







{ "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 },
{ "Pointer_Drag5", 0xFEFD },
{ "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 },
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
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







+















+

+







{ "currency", 0xA4 },
{ "yen", 0xA5 },
{ "brokenbar", 0xA6 },
{ "section", 0xA7 },
{ "diaeresis", 0xA8 },
{ "copyright", 0xA9 },
{ "ordfeminine", 0xAA },
{ "guillemetleft", 0xAB },
{ "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 },
{ "ordmasculine", 0xBA },
{ "masculine", 0xBA },
{ "guillemetright", 0xBB },
{ "guillemotright", 0xBB },
{ "onequarter", 0xBC },
{ "onehalf", 0xBD },
{ "threequarters", 0xBE },
{ "questiondown", 0xBF },
{ "Agrave", 0xC0 },
{ "Aacute", 0xC1 },
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
508
509
510
511
512
513
514

515

516
517
518
519
520
521
522







-

-







{ "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 },
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
542
543
544
545
546
547
548

549

550
551
552
553
554
555
556







-

-







{ "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 },
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
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







-

-











-

-







{ "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 },
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-









-

-










-

-


















-

-

-

-










-

-



















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-







{ "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 },
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
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







-

-











-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-

-


-

-

-

-

-

-

-

-

-

-





-

-





-

-


-

-

-

-

-

-

-

-

-

-





-

-







{ "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 },
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
972
973
974
975
976
977
978

979
980
981
982
983
984
985







-







{ "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 },
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
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







-

-

-

-

-

-



-

-

-

-

-

-









-

-




-

-

-

-

-

-



-

-
-







{ "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 },
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
1271
1272
1273
1274
1275
1276
1277
















1278
1279
1280
1281
1282
1283
1284







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







{ "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 },
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
1362
1363
1364
1365
1366
1367
1368






















































































































































































































































































































































































































































































































































































































































1369
1370
1371
1372
1373
1374
1375







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







{ "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 },
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
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







+


















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







{ "XF86TouchpadOff", 0x1008FFB1 },
{ "XF86AudioMicMute", 0x1008FFB2 },
{ "XF86Keyboard", 0x1008FFB3 },
{ "XF86WWAN", 0x1008FFB4 },
{ "XF86RFKill", 0x1008FFB5 },
{ "XF86AudioPreset", 0x1008FFB6 },
{ "XF86RotationLockToggle", 0x1008FFB7 },
{ "XF86FullScreen", 0x1008FFB8 },
{ "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 },
{ "XF86BrightnessAuto", 0x100810F4 },
{ "XF86DisplayOff", 0x100810F5 },
{ "XF86Info", 0x10081166 },
{ "XF86AspectRatio", 0x10081177 },
{ "XF86DVD", 0x10081185 },
{ "XF86Audio", 0x10081188 },
{ "XF86ChannelUp", 0x10081192 },
{ "XF86ChannelDown", 0x10081193 },
{ "XF86Break", 0x1008119B },
{ "XF86VideoPhone", 0x100811A0 },
{ "XF86ZoomReset", 0x100811A4 },
{ "XF86Editor", 0x100811A6 },
{ "XF86GraphicsEditor", 0x100811A8 },
{ "XF86Presentation", 0x100811A9 },
{ "XF86Database", 0x100811AA },
{ "XF86Voicemail", 0x100811AC },
{ "XF86Addressbook", 0x100811AD },
{ "XF86DisplayToggle", 0x100811AF },
{ "XF86SpellCheck", 0x100811B0 },
{ "XF86ContextMenu", 0x100811B6 },
{ "XF86MediaRepeat", 0x100811B7 },
{ "XF8610ChannelsUp", 0x100811B8 },
{ "XF8610ChannelsDown", 0x100811B9 },
{ "XF86Images", 0x100811BA },
{ "XF86NotificationCenter", 0x100811BC },
{ "XF86PickupPhone", 0x100811BD },
{ "XF86HangupPhone", 0x100811BE },
{ "XF86Fn", 0x100811D0 },
{ "XF86Fn_Esc", 0x100811D1 },
{ "XF86FnRightShift", 0x100811E5 },
{ "XF86Numeric0", 0x10081200 },
{ "XF86Numeric1", 0x10081201 },
{ "XF86Numeric2", 0x10081202 },
{ "XF86Numeric3", 0x10081203 },
{ "XF86Numeric4", 0x10081204 },
{ "XF86Numeric5", 0x10081205 },
{ "XF86Numeric6", 0x10081206 },
{ "XF86Numeric7", 0x10081207 },
{ "XF86Numeric8", 0x10081208 },
{ "XF86Numeric9", 0x10081209 },
{ "XF86NumericStar", 0x1008120A },
{ "XF86NumericPound", 0x1008120B },
{ "XF86NumericA", 0x1008120C },
{ "XF86NumericB", 0x1008120D },
{ "XF86NumericC", 0x1008120E },
{ "XF86NumericD", 0x1008120F },
{ "XF86CameraFocus", 0x10081210 },
{ "XF86WPSButton", 0x10081211 },
{ "XF86CameraZoomIn", 0x10081215 },
{ "XF86CameraZoomOut", 0x10081216 },
{ "XF86CameraUp", 0x10081217 },
{ "XF86CameraDown", 0x10081218 },
{ "XF86CameraLeft", 0x10081219 },
{ "XF86CameraRight", 0x1008121A },
{ "XF86AttendantOn", 0x1008121B },
{ "XF86AttendantOff", 0x1008121C },
{ "XF86AttendantToggle", 0x1008121D },
{ "XF86LightsToggle", 0x1008121E },
{ "XF86ALSToggle", 0x10081230 },
{ "XF86Buttonconfig", 0x10081240 },
{ "XF86Taskmanager", 0x10081241 },
{ "XF86Journal", 0x10081242 },
{ "XF86ControlPanel", 0x10081243 },
{ "XF86AppSelect", 0x10081244 },
{ "XF86Screensaver", 0x10081245 },
{ "XF86VoiceCommand", 0x10081246 },
{ "XF86Assistant", 0x10081247 },
{ "XF86EmojiPicker", 0x10081249 },
{ "XF86Dictate", 0x1008124A },
{ "XF86BrightnessMin", 0x10081250 },
{ "XF86BrightnessMax", 0x10081251 },
{ "XF86KbdInputAssistPrev", 0x10081260 },
{ "XF86KbdInputAssistNext", 0x10081261 },
{ "XF86KbdInputAssistPrevgroup", 0x10081262 },
{ "XF86KbdInputAssistNextgroup", 0x10081263 },
{ "XF86KbdInputAssistAccept", 0x10081264 },
{ "XF86KbdInputAssistCancel", 0x10081265 },
{ "XF86RightUp", 0x10081266 },
{ "XF86RightDown", 0x10081267 },
{ "XF86LeftUp", 0x10081268 },
{ "XF86LeftDown", 0x10081269 },
{ "XF86RootMenu", 0x1008126A },
{ "XF86MediaTopMenu", 0x1008126B },
{ "XF86Numeric11", 0x1008126C },
{ "XF86Numeric12", 0x1008126D },
{ "XF86AudioDesc", 0x1008126E },
{ "XF863DMode", 0x1008126F },
{ "XF86NextFavorite", 0x10081270 },
{ "XF86StopRecord", 0x10081271 },
{ "XF86PauseRecord", 0x10081272 },
{ "XF86VOD", 0x10081273 },
{ "XF86Unmute", 0x10081274 },
{ "XF86FastReverse", 0x10081275 },
{ "XF86SlowReverse", 0x10081276 },
{ "XF86Data", 0x10081277 },
{ "XF86OnScreenKeyboard", 0x10081278 },
{ "XF86PrivacyScreenToggle", 0x10081279 },
{ "XF86SelectiveScreenshot", 0x1008127A },
{ "XF86Macro1", 0x10081290 },
{ "XF86Macro2", 0x10081291 },
{ "XF86Macro3", 0x10081292 },
{ "XF86Macro4", 0x10081293 },
{ "XF86Macro5", 0x10081294 },
{ "XF86Macro6", 0x10081295 },
{ "XF86Macro7", 0x10081296 },
{ "XF86Macro8", 0x10081297 },
{ "XF86Macro9", 0x10081298 },
{ "XF86Macro10", 0x10081299 },
{ "XF86Macro11", 0x1008129A },
{ "XF86Macro12", 0x1008129B },
{ "XF86Macro13", 0x1008129C },
{ "XF86Macro14", 0x1008129D },
{ "XF86Macro15", 0x1008129E },
{ "XF86Macro16", 0x1008129F },
{ "XF86Macro17", 0x100812A0 },
{ "XF86Macro18", 0x100812A1 },
{ "XF86Macro19", 0x100812A2 },
{ "XF86Macro20", 0x100812A3 },
{ "XF86Macro21", 0x100812A4 },
{ "XF86Macro22", 0x100812A5 },
{ "XF86Macro23", 0x100812A6 },
{ "XF86Macro24", 0x100812A7 },
{ "XF86Macro25", 0x100812A8 },
{ "XF86Macro26", 0x100812A9 },
{ "XF86Macro27", 0x100812AA },
{ "XF86Macro28", 0x100812AB },
{ "XF86Macro29", 0x100812AC },
{ "XF86Macro30", 0x100812AD },
{ "XF86MacroRecordStart", 0x100812B0 },
{ "XF86MacroRecordStop", 0x100812B1 },
{ "XF86MacroPresetCycle", 0x100812B2 },
{ "XF86MacroPreset1", 0x100812B3 },
{ "XF86MacroPreset2", 0x100812B4 },
{ "XF86MacroPreset3", 0x100812B5 },
{ "XF86KbdLcdMenu1", 0x100812B8 },
{ "XF86KbdLcdMenu2", 0x100812B9 },
{ "XF86KbdLcdMenu3", 0x100812BA },
{ "XF86KbdLcdMenu4", 0x100812BB },
{ "XF86KbdLcdMenu5", 0x100812BC },
{ "SunFA_Grave", 0x1005FF00 },
{ "SunFA_Circum", 0x1005FF01 },
{ "SunFA_Tilde", 0x1005FF02 },
{ "SunFA_Acute", 0x1005FF03 },
{ "SunFA_Diaeresis", 0x1005FF04 },
{ "SunFA_Cedilla", 0x1005FF05 },
{ "SunF36", 0x1005FF10 },
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.
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
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,
    CONST86 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,
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+







    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 argc, CONST84 char **argv, char *widgRec,
	    int flags)
}
declare 30 {
    void Tk_ConfigureWindow(Tk_Window tkwin,
	    unsigned int valueMask, XWindowChanges *valuePtr)
}
declare 31 {
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
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)
    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,
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336







-
+







}
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}} {
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
344
345
346
347
348
349
350

351
352
353

354
355
356
357
358
359
360
361







-
+


-
+







	    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)
    CONST84_RETURN char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
}
declare 84 {
    const char *Tk_GetBinding(Tcl_Interp *interp,
    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 {
399
400
401
402
403
404
405
406
407


408
409
410
411
412
413
414
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)
    ClientData Tk_GetImageMasterData(Tcl_Interp *interp,
	    const char *name, CONST86 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
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)
	    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
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482







-
+







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,
    void Tk_ImageChanged(Tk_ImageMaster 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)
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
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)
    CONST84_RETURN char *Tk_NameOf3DBorder(Tk_3DBorder border)
}
declare 131 {
    const char *Tk_NameOfAnchor(Tk_Anchor anchor)
    CONST84_RETURN char *Tk_NameOfAnchor(Tk_Anchor anchor)
}
declare 132 {
    const char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
    CONST84_RETURN char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
}
declare 133 {
    const char *Tk_NameOfCapStyle(int cap)
    CONST84_RETURN char *Tk_NameOfCapStyle(int cap)
}
declare 134 {
    const char *Tk_NameOfColor(XColor *colorPtr)
    CONST84_RETURN char *Tk_NameOfColor(XColor *colorPtr)
}
declare 135 {
    const char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
    CONST84_RETURN char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
}
declare 136 {
    const char *Tk_NameOfFont(Tk_Font font)
    CONST84_RETURN char *Tk_NameOfFont(Tk_Font font)
}
declare 137 {
    const char *Tk_NameOfImage(Tk_ImageModel model)
    CONST84_RETURN char *Tk_NameOfImage(Tk_ImageMaster model)
}
declare 138 {
    const char *Tk_NameOfJoinStyle(int join)
    CONST84_RETURN char *Tk_NameOfJoinStyle(int join)
}
declare 139 {
    const char *Tk_NameOfJustify(Tk_Justify justify)
    CONST84_RETURN char *Tk_NameOfJustify(Tk_Justify justify)
}
declare 140 {
    const char *Tk_NameOfRelief(int relief)
    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, const char **argv,
	    Tk_Window tkwin, int *argcPtr, CONST84 char **argv,
	    const Tk_ArgvInfo *argTable, int flags)
}
declare 144 {deprecated {function signature changed}} {
declare 144 {
    void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height)
}
declare 145 {deprecated {function signature changed}} {
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 {deprecated {function signature changed}} {
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 {deprecated {function signature changed}} {
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)
740
741
742
743
744
745
746
747

748
749
750
751
752
753
754
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,
    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
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,
	    char *recordPtr, Tk_OptionTable optionTable,
	    Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 205 {
    Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, void *recordPtr,
    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
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







-
+


-
+







-
+







	    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,
    int	 Tk_InitOptions(Tcl_Interp *interp, char *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {nostub {Don't use this function in a stub-enabled extension}} {
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, void *recordPtr,
    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)
}
939
940
941
942
943
944
945
946

947
948
949
950
951

952
953
954
955
956
957
958
939
940
941
942
943
944
945

946
947
948
949
950

951
952
953
954
955
956
957
958







-
+




-
+







}

# New in 8.4a5
#
declare 245 {
    void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
declare 246 {deprecated {function signature changed}} {
declare 246 {
    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}} {
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
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,
	    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,
	    void *recordPtr, Tk_Window tkwin, int x, int y, int width,
	    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,
	    void *recordPtr, Tk_Window tkwin)
	    char *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,
	    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)
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
1064
1065
1066
1067
1068
1069
1070



1071














1072




1073
1074
1075
1076
1077
1078
1079







-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-







# 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 {
declare 290 {
    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,
    void TkUnusedStubEntry(void)
	    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

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
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







-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+




-
+





-
-
-
+
+
-
+




















-
+







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 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,
    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 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,
    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.

Changes to generic/tk.h.
13
14
15
16
17
18
19
20
21


22
23







24
25
26
27
28
29
30
13
14
15
16
17
18
19


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37







-
-
+
+


+
+
+
+
+
+
+







 * 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
#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 6)
#	error Tk 8.6 must be compiled with tcl.h from Tcl 8.6 or better
#endif

#ifndef CONST84
#   define CONST84 const
#   define CONST84_RETURN const
#endif
#ifndef CONST86
#   define CONST86 CONST84
#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.
48
49
50
51
52
53
54
55
56


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71



72
73
74


75
76
77
78
79
80
81
55
56
57
58
59
60
61


62
63
64
65
66
67
68
69
70
71
72
73
74
75



76
77
78
79


80
81
82
83
84
85
86
87
88







-
-
+
+












-
-
-
+
+
+

-
-
+
+







#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)
 * unix/configure.in	(2 LOC Major, 2 LOC minor, 1 LOC patch)
 * win/configure.in	(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_MINOR_VERSION	6
#define TK_RELEASE_LEVEL	TCL_FINAL_RELEASE
#define TK_RELEASE_SERIAL	16

#define TK_VERSION		"8.7"
#define TK_PATCH_LEVEL		"8.7a4"
#define TK_VERSION		"8.6"
#define TK_PATCH_LEVEL		"8.6.16"

/*
 * 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.
 *
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132

133
134
135
136
137
138
139
105
106
107
108
109
110
111




112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134

135
136
137
138
139
140
141
142







-
-
-
-
















-
+






-
+







     || 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
#define Tk_ImageModel Tk_ImageMaster
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_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
191
192
193
194
195
196
197


198
199
200




201
202
203
204
205
206
207




208
209
210
211




212
213
214
215
216
217
218







-
-
+


-
-
-
-
+
+
+
+



-
-
-
-
+
+
+
+
-
-
-
-







    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
    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 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
				 * 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 offsetof
				 * macro to generate values for it.
				 * TCL_INDEX_NONE means don't store the
				 * internal representation in the record. */
				 * 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. */
#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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
233
234
235
236
237
238
239







240
241
242
243
244

245
246
247
248
249
250
251







-
-
-
-
-
-
-





-








/*
 * 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. */
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
267
268
269
270
271
272
273


274

275
276
277
278
279
280
281







-
-
+
-







} 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))
#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
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331

332
333
334
335
336
337
338
339
340
341
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317


318



319
320
321
322
323
324
325







-
+















-
+



-
-
+
-
-
-







				 * 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
				 * 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 {
    void *recordPtr;		/* The data structure in which to restore
    char *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. */
    int 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. */
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366


367
368
369
370
371
372
373
374
375
335
336
337
338
339
340
341

342







343
344
345

346
347
348
349
350
351
352







-

-
-
-
-
-
-
-
+
+

-







/*
 * 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, CONST84 char *value, char *widgRec, int offset);
typedef CONST86 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
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401


402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
363
364
365
366
367
368
369

370
371
372
373
374
375



376
377
378



379
380
381

382
383
384
385
386
387
388
389







-
+





-
-
-
+
+

-
-
-



-
+







 * 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
    CONST86 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
    int offset;			/* Where in widget record to store value; use
				 * Tk_Offset 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;
    CONST86 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;

/*
442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460

461
462
463

464
465

466
467

468
469
470
471
472
473
474
415
416
417
418
419
420
421


422

423
424
425
426
427
428
429
430

431
432
433

434
435

436
437

438
439
440
441
442
443
444
445







-
-
+
-








-
+


-
+

-
+

-
+







 * (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)
#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
    CONST86 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
    char *src;			/* Value to be used in setting dst; usage
				 * depends on type. */
    void *dst;			/* Address of value to be modified; usage
    char *dst;			/* Address of value to be modified; usage
				 * depends on type. */
    const char *help;		/* Documentation message describing this
    CONST86 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.
 */
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
576
577
578
579
580
581
582



583

584
585
586
587
588
589
590







-
-
-

-








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. */
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
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







-
+




-
+







-
+










-
+







 * (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))
 *	    (((who)->size <= Tk_Offset(name, which)) ? NULL :(name)->which))
 */

#define Tk_GetClassProc(procs, which) \
    (((procs) == NULL) ? NULL : \
    (((procs)->size <= offsetof(Tk_ClassProcs, which)) ? NULL:(procs)->which))
    (((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.
 */

#define Tk_GeomLostSlaveProc Tk_GeomLostContentProc
#define Tk_GeomLostContentProc Tk_GeomLostSlaveProc
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;
    Tk_GeomLostContentProc *lostSlaveProc;
				/* 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;

/*
781
782
783
784
785
786
787
788

789
790
791
792
793
794
795
796
797
798
748
749
750
751
752
753
754

755
756
757

758
759
760
761
762
763
764







-
+


-







    (((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
/* Tk_InternalBorderWidth is 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) \
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
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







-
+



















-
+




-
-
-
-







    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)
#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;
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
#ifdef TK_USE_INPUT_METHODS
    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.
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
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







-
+















-
-
+

-
-
-








-
-
+

-
+

-
-
-








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;
    CONST86 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
    int 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
    int tagSpace;		/* Total amount of tag space available at
				 * tagPtr. */
    size_t numTags;		/* Number of tag slots actually used at
    int 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. */
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
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







-
+






-
-
-
-


-
+

-
+


-
+
-
-
-
-
-
-
-
-
-
-
-












-
-





-
-
+
+
-
-
+
-
-
-

+
+
+




+
+
+
+
+
+
+


-




-
+

-
-
+

-
-
-



-
+







#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
#ifdef USE_OLD_CANVAS
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[]);
		    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[],
		    Tk_Item *itemPtr, int objc, 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[]);
		    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]);
#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,
#ifdef USE_OLD_CANVAS
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    size_t index);
typedef size_t	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Tk_Item *itemPtr, char *indexString, int *indexPtr);
		    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 int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, int *indexPtr);
#endif /* USE_OLD_CANVAS */
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);
#ifdef USE_OLD_CANVAS
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, char *string);
#else
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, Tcl_Obj *string);
#endif /* USE_OLD_CANVAS */
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
    CONST86 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
    int 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
    CONST86 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
1105
1106
1107
1108
1109
1110
1111



1112
1113
1114
1115
1116
1117
1118
1119







-
-
-
+







    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. */
    char *reserved1;		/* Reserved for future extension. */
    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
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
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







-
-
+

-
+

-
-
-



-
-
+



-
-
-







    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
    int selectFirst;		/* Character index of first selected
				 * character. Writable by items. */
    size_t selectLast;		/* Character index of last selected character.
    int 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
    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. */
#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
1299
1300
1301
1302
1303
1304
1305
1306

1307
1308

1309
1310
1311
1312


1313
1314
1315
1316
1317
1318
1319
1227
1228
1229
1230
1231
1232
1233

1234
1235

1236
1237
1238


1239
1240
1241
1242
1243
1244
1245
1246
1247







-
+

-
+


-
-
+
+







 *
 * 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)
#ifdef USE_OLD_IMAGE
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc,
	char **argv, Tk_ImageType *typePtr, Tk_ImageModel model,
	char **argv, Tk_ImageType *typePtr, Tk_ImageMaster 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,
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, CONST86 char *name, int objc,
	Tcl_Obj *const objv[], CONST86 Tk_ImageType *typePtr, Tk_ImageMaster 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);
1329
1330
1331
1332
1333
1334
1335
1336

1337
1338
1339
1340
1341
1342
1343
1257
1258
1259
1260
1261
1262
1263

1264
1265
1266
1267
1268
1269
1270
1271







-
+







 * 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. */
    CONST86 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;
1441
1442
1443
1444
1445
1446
1447
1448

1449
1450
1451
1452
1453
1454
1455
1369
1370
1371
1372
1373
1374
1375

1376
1377
1378
1379
1380
1381
1382
1383







-
+







/*
 * 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 */
    CONST86 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;
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1473
1474
1475
1476
1477
1478
1479

1480
1481
1482
1483
1484
1485
1486







-







 * 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
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519







-








/* 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, \
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
1540
1541
1542
1543
1544
1545
1546

1547
1548
1549
1550




1551
1552

1553
1554
1555
1556
1557
1558
1559







-
+



-
-
-
-


-







 */

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);
	CONST86 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.
 *
 *----------------------------------------------------------------------
1647
1648
1649
1650
1651
1652
1653
1654

1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1568
1569
1570
1571
1572
1573
1574

1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587







-
+





-







#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.
 * 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.
 */

#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
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1606
1607
1608
1609
1610
1611
1612

1613
1614
1615
1616
1617
1618
1619







-







#   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 */

/*
Changes to generic/tk3d.c.
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
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







-
+
-















+




-
-
+
+
-
-
+


-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

+
-
-
-
-
+
+
+
+
+


+
+
+







 * Tk_GetRelief --
 *
 *	Parse a relief description and return the corresponding relief value,
 *	or an error.
 *
 * Results:
 *	A standard Tcl return value. If all goes well then *reliefPtr is
 *	filled in with one of the values TK_RELIEF_RAISED, TK_RELIEF_FLAT, or
 *	filled in with one of the values TK_RELIEF_*
 *	TK_RELIEF_SUNKEN.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

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;
    int relief;

    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)
	relief = TK_RELIEF_FLAT;
    } else if ((c == 'g') && (strncmp(name, "groove", length) == 0)) {
	    && (length >= 2)) {
	*reliefPtr = TK_RELIEF_GROOVE;
	relief = 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;
	relief = TK_RELIEF_RAISED;
    } else if ((c == 'r') && (strncmp(name, "ridge", length) == 0)
	    && (length >= 2)) {
	relief = TK_RELIEF_RIDGE;
    } else if ((c == 's') && (strncmp(name, "solid", length) == 0)
	    && (length >= 2)) {
	relief = TK_RELIEF_SOLID;
    } else if ((c == 's') && (strncmp(name, "sunken", length) == 0)
	    && (length >= 2)) {
	relief = TK_RELIEF_SUNKEN;
    } else {
	if (interp) {
	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);
	    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;
    }
    if (reliefPtr) {
	*reliefPtr = relief;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * Tk_NameOfRelief --
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384

1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1382
1383
1384
1385
1386
1387
1388

1389
1390

1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404







-
+

-
+













	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_NewIntObj(borderPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(borderPtr->objRefCount));
		    Tcl_NewIntObj(borderPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tk3d.h.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * tk3d.h --
 *
 *	Declarations of types and functions shared by the 3d border module.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK3D
#define _TK3D
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47







-
+








-
+







    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
    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 objRefCount and
				 * resourceRefCount are both 0. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
    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
Changes to generic/tkArgv.c.
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116







-
+







	if (length > 0) {
	    c = curArg[1];
	} else {
	    c = 0;
	}

	/*
	 * Loop throught the argument descriptors searching for one with the
	 * Loop through the argument descriptors searching for one with the
	 * matching key string. If found, leave a pointer to it in matchPtr.
	 */

	matchPtr = NULL;
	for (i = 0; i < 2; i++) {
	    if (i == 0) {
		infoPtr = argTable;
224
225
226
227
228
229
230
231

232
233

234
235
236
237
238
239
240
241
242

243
244

245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263

264
265
266
267
268
269
270
224
225
226
227
228
229
230

231
232

233
234
235
236
237
238
239
240
241

242
243

244
245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262

263
264
265
266
267
268
269
270







-
+

-
+








-
+

-
+











-
+






-
+







		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_FUNC: {
	    typedef int (ArgvFunc)(char *, const char *, const char *);
	    ArgvFunc *handlerProc = (ArgvFunc *)infoPtr->src;
	    ArgvFunc *handlerProc = (ArgvFunc *) infoPtr->src;

	    if (handlerProc((char *)infoPtr->dst, infoPtr->key, argv[srcIndex])) {
	    if (handlerProc(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;
	    ArgvGenFunc *handlerProc = (ArgvGenFunc *) infoPtr->src;

	    argc = handlerProc((char *)infoPtr->dst, interp, infoPtr->key, argc,
	    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);
	    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_AddOption(tkwin, infoPtr->dst, 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_AddOption(tkwin, infoPtr->dst, argv[srcIndex],
		    TK_INTERACTIVE_PRIO);
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_OPTION_NAME_VALUE:
	    if (argc < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
Changes to generic/tkArray.h.
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15







-
+







/*
 * 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.
 * Copyright (c) 2018-2019 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
Changes to generic/tkAtom.c.
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166







-
+







	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);
	Tcl_SetHashValue(hPtr, name);
    }
    return (const char *)Tcl_GetHashValue(hPtr);
}

/*
 *--------------------------------------------------------------
 *
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215







-
+










	}

	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);
	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
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17








-
-
+
+







/*
 * 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.
 * Copyright (c) 1998 Scriptics Corporation.
 * Copyright (c) 2018-2019 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"
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
27
28
29
30
31
32
33








34
35
36
37
38
39
40







-
-
-
-
-
-
-
-








#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.
 *
58
59
60
61
62
63
64
65

66
67
68
69

70
71
72
73
74
75


76
77
78
79

80
81
82
83
84
85
86
50
51
52
53
54
55
56

57
58
59
60

61
62
63
64
65


66
67
68
69
70

71
72
73
74
75
76
77
78







-
+



-
+




-
-
+
+



-
+







 */

/*
 * 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.
 * This can be achieved by setting PREFER_MOST_SPECIALIZED_EVENT to 1.
 */

#ifndef PREFER_MOST_SPECIALIZED_EVENT
# define PREFER_MOST_SPECIALIZED_EVENT 1
# define PREFER_MOST_SPECIALIZED_EVENT 0
#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.
 * However it should be allowed to express this as <Motion-1-2> in addition. This can be
 * achieved by setting SUPPORT_ADDITIONAL_MOTION_SYNTAX to 1.
 */

#ifndef SUPPORT_ADDITIONAL_MOTION_SYNTAX
# define SUPPORT_ADDITIONAL_MOTION_SYNTAX 1
# define SUPPORT_ADDITIONAL_MOTION_SYNTAX 0 /* set to 1 if wanted */
#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.
 */
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145







-
+








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. */
    TK_DLIST_LINKS(PSEntry);	/* Makes this struct a doubly 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. */
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190







-
+







 * 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) */
/* Defining the whole PromArr_* 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. */
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241







-
+







 *
 * 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
    void *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;

328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334







-
+







 * 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:
 * or pixels to be considered close in space or time.
 */

#define NEARBY_PIXELS	5
#define NEARBY_MS	500

/*
 * The following structure is used in the nameTable of a virtual event table
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421







-
+








/*
 * 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.
 * MULT_CLICKS -	Combination of all the above.
 */

#define DOUBLE		(1<<0)
#define TRIPLE		(1<<1)
#define QUADRUPLE	(1<<2)
#define MULT_CLICKS	(DOUBLE|TRIPLE|QUADRUPLE)

441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
433
434
435
436
437
438
439








440
441
442
443
444
445
446







-
-
-
-
-
-
-
-







    {"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},
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558







-
+







#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
 * 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
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
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







-
+












-
+




+


-
-
+
+













-
-
+
+











-
-
+
+







			    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,
			    void *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);
			    void *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 void		DoWarp(void *clientData);
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 void		ClearLookupTable(LookupTables *lookupTables, void *object);
static void		ClearPromotionLists(Tk_BindingTable bindPtr, void *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;
#if SUPPORT_DEBUGGING
static int BindCount = 0;  /* Can be set or queried from Tcl through 'event debug' subcommand. Otherwise not used. */
#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? */
    unsigned lhsMask,	/* Is this a subset... */
    unsigned rhsMask)	/* ...of this bit field? */
{
    return (lhsMask & rhsMask) == lhsMask;
}

static const char*
SkipSpaces(
    const char* s)
788
789
790
791
792
793
794
795
796
797

798
799
800
801
802
803
804

805
806
807
808
809
810
811
773
774
775
776
777
778
779

780

781

782
783
784
785
786
787
788
789
790
791
792
793
794
795







-

-
+
-






+







    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 (field[0] >= '1' && field[0] <= '5' && 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,
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
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







-
+

-
+




-
+








-
-
+
+















-
-
+
+







    for (i = 0; i < sndMatchPtr->numPats; ++i) {
	if (GetInfo(sndMatchPtr, i)) { sndCount += GetCount(sndMatchPtr, i); }
    }

    return sndCount - fstCount;
}

int
static int
IsKeyEventType(
    unsigned eventType)
    int eventType)
{
    return eventType == KeyPress || eventType == KeyRelease;
}

int
static int
IsButtonEventType(
    unsigned eventType)
{
    return eventType == ButtonPress || eventType == ButtonRelease;
}

static int
MatchEventNearby(
    const XEvent *lhs,	/* previous button event */
    const XEvent *rhs)	/* current button event */
    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 */
    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 */
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
909
910
911
912
913
914
915

916
917
918
919
920
921
922
923







-
+







    PSList_Append(pool, psEntry);
}

static void
ClearList(
    PSList *psList,
    PSList *pool,
    ClientData object)
    void *object)
{
    assert(psList);
    assert(pool);

    if (object) {
	PSEntry *psEntry;
	PSEntry *psNext;
989
990
991
992
993
994
995
996
997
998
999
1000

1001
1002
1003
1004
1005
1006
1007
973
974
975
976
977
978
979





980
981
982
983
984
985
986
987







-
-
-
-
-
+







    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;
    return 5;
}

static void
SetupPatternKey(
    PatternTableKey *key,
    const PatSeq *psPtr)
{
1109
1110
1111
1112
1113
1114
1115
1116

1117
1118
1119
1120
1121
1122
1123
1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103







-
+







{
    PatternTableKey key;
    Tcl_HashEntry *hPtr;

    assert(lookupTables);
    assert(eventPtr);

    /* otherwise on some systems the key contains uninitialized bytes */
    /* 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;
1153
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147







-
+







 *	None.
 *
 *--------------------------------------------------------------
 */
static void
ClearLookupTable(
    LookupTables *lookupTables,
    ClientData object)
    void *object)
{
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    Tcl_HashEntry *nextPtr;
    PSList *pool = &lookupTables->entryPool;

    assert(lookupTables);
1203
1204
1205
1206
1207
1208
1209
1210

1211
1212

1213
1214
1215
1216
1217
1218
1219
1220
1183
1184
1185
1186
1187
1188
1189

1190
1191

1192

1193
1194
1195
1196
1197
1198
1199







-
+

-
+
-







 *
 *--------------------------------------------------------------
 */

static void
ClearPromotionLists(
    Tk_BindingTable bindPtr,
    ClientData object)
    void *object)
{
    unsigned newArraySize = 0;
    size_t i, 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)) {
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
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







-
+













-
+


-
+



-
+


-
+






-
+






-
+


-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 * Side effects:
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

/*
 * Windoze compiler does not allow the definition of these static variables inside a function,
 * Windows 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 */
    /* Otherwise virtual events can't be supported. */
    assert(sizeof(XEvent) >= sizeof(XVirtualEvent));

    /* type of TkPattern.info is well defined? */
    /* Is type of TkPattern.info well defined? */
    assert(sizeof(Info) >= sizeof(KeySym));
    assert(sizeof(Info) >= sizeof(unsigned));

    /* ensure that our matching algorithm is working (when testing detail) */
    /* 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 */
    /* 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 */
    /* 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 */
    /* 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));
    /* This must be a union, not a struct, otherwise comparison with NULL will not work. */
    assert(Tk_Offset(Detail, name) == Tk_Offset(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));
    /* We use some constraints about X*Event. */
    assert(Tk_Offset(XButtonEvent, time) == Tk_Offset(XMotionEvent, time));
    assert(Tk_Offset(XButtonEvent, x_root) == Tk_Offset(XMotionEvent, x_root));
    assert(Tk_Offset(XButtonEvent, y_root) == Tk_Offset(XMotionEvent, y_root));
    assert(Tk_Offset(XCreateWindowEvent, border_width) == Tk_Offset(XConfigureEvent, border_width));
    assert(Tk_Offset(XCreateWindowEvent, width) == Tk_Offset(XConfigureEvent, width));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XCirculateRequestEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XConfigureEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XGravityEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XMapEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XReparentEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XUnmapEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, x) == Tk_Offset(XConfigureEvent, x));
    assert(Tk_Offset(XCreateWindowEvent, x) == Tk_Offset(XGravityEvent, x));
    assert(Tk_Offset(XCreateWindowEvent, y) == Tk_Offset(XConfigureEvent, y));
    assert(Tk_Offset(XCreateWindowEvent, y) == Tk_Offset(XGravityEvent, y));
    assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XEnterWindowEvent, time));
    assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XLeaveWindowEvent, time));
    assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XKeyEvent, time));
    assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XButtonEvent, root));
    assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XCrossingEvent, root));
    assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XMotionEvent, root));
    assert(Tk_Offset(XKeyEvent, state) == Tk_Offset(XButtonEvent, state));
    assert(Tk_Offset(XKeyEvent, state) == Tk_Offset(XMotionEvent, state));
    assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XButtonEvent, subwindow));
    assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XCrossingEvent, subwindow));
    assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XMotionEvent, subwindow));
    assert(Tk_Offset(XKeyEvent, time) == Tk_Offset(XButtonEvent, time));
    assert(Tk_Offset(XKeyEvent, time) == Tk_Offset(XMotionEvent, time));
    assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XButtonEvent, x));
    assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XCrossingEvent, x));
    assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XMotionEvent, x));
    assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XButtonEvent, x_root));
    assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XCrossingEvent, x_root));
    assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XMotionEvent, x_root));
    assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XButtonEvent, y));
    assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XCrossingEvent, y));
    assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XMotionEvent, y));
    assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XButtonEvent, y_root));
    assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XCrossingEvent, y_root));
    assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(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) {
1628
1629
1630
1631
1632
1633
1634
1635

1636
1637
1638
1639
1640
1641
1642
1607
1608
1609
1610
1611
1612
1613

1614
1615
1616
1617
1618
1619
1620
1621







-
+







 *--------------------------------------------------------------
 */

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. */
    void *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. */
{
1727
1728
1729
1730
1731
1732
1733
1734

1735
1736
1737
1738
1739
1740
1741
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715
1716
1717
1718
1719
1720







-
+







 *--------------------------------------------------------------
 */

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. */
    void *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);
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1779
1780
1781
1782
1783
1784
1785

1786
1787
1788
1789
1790
1791
1792
1793







-
+







 *--------------------------------------------------------------
 */

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. */
    void *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);
1838
1839
1840
1841
1842
1843
1844
1845

1846
1847
1848
1849
1850
1851
1852
1817
1818
1819
1820
1821
1822
1823

1824
1825
1826
1827
1828
1829
1830
1831







-
+







 *--------------------------------------------------------------
 */

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. */
    void *object)		/* Token for object. */
{
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);

    if ((hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object))) {
1929
1930
1931
1932
1933
1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1908
1909
1910
1911
1912
1913
1914

1915
1916
1917
1918
1919
1920
1921
1922







-
+







 */

static void
RemovePatSeqFromPromotionLists(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr)		/* Remove this pattern sequence. */
{
    unsigned i;
    size_t i;

    assert(bindPtr);
    assert(psPtr);

    for (i = 0; i < PromArr_Size(bindPtr->promArr); ++i) {
	PSList *psList = PromArr_Get(bindPtr->promArr, i);
	PSEntry *psEntry;
2027
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2006
2007
2008
2009
2010
2011
2012

2013
2014
2015
2016
2017
2018
2019
2020







-
+







 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteAllBindings(
    Tk_BindingTable bindPtr,	/* Table in which to delete bindings. */
    ClientData object)		/* Token for object. */
    void *object)		/* Token for object. */
{
    PatSeq *psPtr;
    PatSeq *nextPtr;
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);
2155
2156
2157
2158
2159
2160
2161
2162

2163
2164
2165
2166
2167
2168
2169
2134
2135
2136
2137
2138
2139
2140

2141
2142
2143
2144
2145
2146
2147
2148







-
+







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. */
    void **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;
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
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







-
-
-
-
-
-
-
-
+
+









-
-
-
-
-
-
-
-
-









-
+






-
+









-
+







    }

    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".
     * Compute current time needed for "event generate",
     * and reset counters for Key and Button events.
     */

    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 */
	/* 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 */
	    /* 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 */
	/* 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) {
2371
2372
2373
2374
2375
2376
2377
2378

2379
2380
2381
2382
2383
2384
2385
2335
2336
2337
2338
2339
2340
2341

2342
2343
2344
2345
2346
2347
2348
2349







-
+







    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? */
	/* 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);
2393
2394
2395
2396
2397
2398
2399
2400

2401
2402
2403
2404

2405
2406
2407
2408
2409
2410
2411
2357
2358
2359
2360
2361
2362
2363

2364
2365
2366
2367

2368
2369
2370
2371
2372
2373
2374
2375







-
+



-
+







	     * 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 */
		    /* 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 */
		    /* We have promoted sequences, adjust array size. */
		    arraySize = Max(i + 1, arraySize);
		}
	    }
	}
    }

    /*
2422
2423
2424
2425
2426
2427
2428
2429

2430
2431
2432
2433
2434
2435
2436
2386
2387
2388
2389
2390
2391
2392

2393
2394
2395
2396
2397
2398
2399
2400







-
+








	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 */
	    /* 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)) {
2475
2476
2477
2478
2479
2480
2481
2482

2483
2484
2485
2486
2487
2488
2489
2439
2440
2441
2442
2443
2444
2445

2446
2447
2448
2449
2450
2451
2452
2453







-
+







		    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 */
	    /* Null is added to the scripts string to separate the various scripts. */
	    Tcl_DStringAppend(&scripts, "", 1);
	}
    }

    PromArr_SetSize(bindPtr->promArr, arraySize);

    /*
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
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







-
+











-
+







		    }
		    break;
		}
	    }
	}

	if (!PSList_IsEmpty(psList)) {
	    /* we still have promoted sequences, adjust array size */
	    /* 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 */
	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:
2599
2600
2601
2602
2603
2604
2605
2606

2607
2608
2609
2610
2611
2612
2613
2563
2564
2565
2566
2567
2568
2569

2570
2571
2572
2573
2574
2575
2576
2577







-
+







     * 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);
	size_t len = strlen(p);
	int code;

	if (!bindInfoPtr->deleted) {
	    ++screenPtr->bindingDepth;
	}
	Tcl_AllowExceptions(interp);

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
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







-
+


















-
+




-
+







 */

/* 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. */
    void *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 */
		return 0; /* We cannot surpass this match. */
	    }
	}
    }

    /* otherwise on some systems the key contains uninitialized bytes */
    /* 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) {
2714
2715
2716
2717
2718
2719
2720
2721

2722
2723
2724
2725
2726
2727
2728
2678
2679
2680
2681
2682
2683
2684

2685
2686
2687
2688
2689
2690
2691
2692







-
+







    return 0;
}

/* helper function */
static int
Compare(
    const PatSeq *fstMatchPtr,
    const PatSeq *sndMatchPtr) /* most recent match */
    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;
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+










-
+







    /* Finally compare modifier masks of last pattern. */

    if (IsSubsetOf(fstModMask, sndModMask)) { ++sndCount; }
    if (IsSubsetOf(sndModMask, fstModMask)) { ++fstCount; }

    return fstCount - sndCount;
}

/* helper function */
static int
IsPSInPSList(
    const PatSeq *psPtr,   /* Is this pattern sequence... */
    const PSList *psList)  /* ...an element of this list of patterns sequence? */
{
    PSEntry *psEntry;

    TK_DLIST_FOREACH(psEntry, psList) {
        if (psEntry->psPtr == psPtr) { return 1; }
    }
    return 0;
}

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. */
    void *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;
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
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







-
+


















-
-
+
+















-
+







	    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
                /* 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 */
		    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.
				 * This is also a final pattern (i.e. the pattern sequence is complete).
				 * 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) {
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
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







-
+



-
+
+


+
-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







				    bestModMaskArr = psEntry->lastModMaskArr;
				    if (physPtrPtr) {
					bestPhysPtr = *physPtrPtr;
				    }
				}
			    } else {
				DEBUG(psEntry->expired = 0;)
				psEntry->keepIt = 1; /* don't remove it from promotion list */
				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.
			     * Not a final pattern, but matching (i.e. successive patterns match the pattern sequence so far),
			     * so promote the pattern sequence to next level if not already promoted in the success list.
			     * But do not promote if count of current pattern is not yet reached.
			     */
			    if (!IsPSInPSList(psPtr, psSuccList)) {
			    if (patPtr->count == psEntry->count) {
				PSEntry *psNewEntry;
				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 */
				    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. */
				}
			    } else {
			        /*
				 * Pattern sequence is already present in the success list.
				 */

				DEBUG(psEntry->expired = 0;)
				psEntry->keepIt = 1; /* Don't remove it from promotion list. */
			    }
			}
		    }
		}
	    }
	}
    }
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
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







-
+











-
-
+
+
+
+
+
+
+
+
+
+
+
+









-
-
-
-
-
-
-
-
-
-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_EventObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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 };
    static const char *const optionStrings[] = { "add",
#if SUPPORT_DEBUGGING
	"debug",
#endif
	"delete", "generate", "info", NULL
    };
    enum options { EVENT_ADD,
#if SUPPORT_DEBUGGING
	EVENT_DEBUG,
#endif
	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;

3381
3382
3383
3384
3385
3386
3387
















3388
3389
3390
3391
3392
3393
3394
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	for (i = 3; i < objc; ++i) {
	    event = Tcl_GetString(objv[i]);
	    if (!CreateVirtualEvent(interp, vetPtr, name, event)) {
		return TCL_ERROR;
	    }
	}
	break;
#if SUPPORT_DEBUGGING
    case EVENT_DEBUG:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "debug number");
	    return TCL_ERROR;
	}
	if (objc < 3) {
	    Tcl_SetObjResult(interp,
		Tcl_NewIntObj(BindCount));
	    return TCL_OK;
	}
	if (Tcl_GetIntFromObj(interp, objv[2], &BindCount) != TCL_OK) {
	    return TCL_ERROR;
	}
	return TCL_OK;
#endif
    case EVENT_DELETE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "virtual ?sequence ...?");
	    return TCL_ERROR;
	}
	name = Tcl_GetString(objv[2]);
	if (objc == 3) {
3541
3542
3543
3544
3545
3546
3547
3548

3549
3550
3551
3552
3553
3554
3555
3545
3546
3547
3548
3549
3550
3551

3552
3553
3554
3555
3556
3557
3558
3559







-
+







    assert(eventString);

    if (!(virtUid = GetVirtualEventUid(interp, virtString))) {
	return 0;
    }

    /*
     * Find/create physical event
     * Find/create physical event.
     */

    if (!(psPtr = FindSequence(interp, &vetPtr->lookupTables, NULL, eventString, 1, 0, NULL))) {
	return 0;
    }
    assert(TEST_PSENTRY(psPtr));

3649
3650
3651
3652
3653
3654
3655
3656

3657
3658
3659
3660
3661
3662
3663
3653
3654
3655
3656
3657
3658
3659

3660
3661
3662
3663
3664
3665
3666
3667







-
+








	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 */
	    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) {
3971
3972
3973
3974
3975
3976
3977




3978

3979
3980
3981
3982
3983
3984
3985
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994







+
+
+
+

+








    synch = 1;
    warp = 0;
    pos = TCL_QUEUE_TAIL;

    for (i = 2; i < (unsigned) objc; i += 2) {
	Tcl_Obj *optionPtr, *valuePtr;
#if defined(_MSC_VER)
        /* Work around MSVC compiler optimization bug, see [d93c8175fd]. */
	volatile int badOpt = 0;
#else
	int badOpt = 0;
#endif
	int index;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, fieldStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4045
4046
4047
4048
4049
4050
4051



4052
4053
4054
4055
4056
4057
4058







-
-
-







	    }
	    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) {
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
4420
4421
4422
4423
4424
4425
4426









4427




4428
4429
4430
4431
4432
4433
4434
4435
4436
4437







-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+
+







		}
		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->flags & TK_DISPLAY_IN_WARP)) {
            if (!dispPtr->warpWindow) {
                TkpWarpPointer(dispPtr);
                XForceScreenSaver(dispPtr->display, ScreenSaverReset);
            }
		Tcl_DoWhenIdle(DoWarp, dispPtr);
		dispPtr->flags |= TK_DISPLAY_IN_WARP;
	    }
	}

	/*
	 * Now we have constructed the event, inject it into the event handling
	 * code.
	 */

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
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







-
+

-
+










-
-
-
+
+
+

-
+

-
-
-
-
-
+
-

-
-
+
+
-
-
-
+
+
-
-
+
+
+

+
-
-
-
-
-
-
+
+
+
+
+
+
+
+

+







    *tkwinPtr = tkwin;
    return 1;
}

/*
 *-------------------------------------------------------------------------
 *
 * TkDoWarpWrtWin --
 * DoWarp --
 *
 *	Perform warping of mouse pointer with respect to a window.
 *	Perform warping of mouse pointer. Executed as an idle handler only.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Mouse pointer moves to a new location.
 *
 *-------------------------------------------------------------------------
 */

void
TkDoWarpWrtWin(
    TkDisplay *dispPtr)
static void
DoWarp(
    void *clientData)
{
    assert(dispPtr);
    TkDisplay *dispPtr = (TkDisplay *)clientData;

    /*
     * 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.
     */

    assert(clientData);
    if (dispPtr->warpWindow) {

        /*
         * Warping with respect to a window can only be done if the window is
    /*
     * DoWarp was scheduled only if the window was mapped. It needs to be
         * 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,
     * still mapped at the time the present idle callback 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.
         */
     * Finally, the case warpWindow == NULL is special in that it means
     * the whole screen.
     */

    if (!dispPtr->warpWindow ||
        if (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None) {
            TkpWarpPointer(dispPtr);
            XForceScreenSaver(dispPtr->display, ScreenSaverReset);
        }
        Tcl_Release(dispPtr->warpWindow);
        dispPtr->warpWindow = NULL;
            (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None)) {
        TkpWarpPointer(dispPtr);
        XForceScreenSaver(dispPtr->display, ScreenSaverReset);
    }

    if (dispPtr->warpWindow) {
	Tcl_Release(dispPtr->warpWindow);
	dispPtr->warpWindow = NULL;
    }
    dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}

/*
 *-------------------------------------------------------------------------
 *
 * GetVirtualEventUid --
 *
4629
4630
4631
4632
4633
4634
4635
4636

4637
4638
4639
4640
4641
4642
4643
4625
4626
4627
4628
4629
4630
4631

4632
4633
4634
4635
4636
4637
4638
4639







-
+







 *----------------------------------------------------------------------
 */

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
    void *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. */
4837
4838
4839
4840
4841
4842
4843
4844

4845
4846
4847
4848
4849
4850
4851
4833
4834
4835
4836
4837
4838
4839

4840
4841
4842
4843
4844
4845
4846
4847







-
+







    unsigned count = 1;

    assert(eventStringPtr);
    assert(patPtr);
    assert(eventMaskPtr);

    p = *eventStringPtr;
    memset(patPtr, 0, sizeof(TkPattern)); /* otherwise memcmp doesn't work */
    memset(patPtr, 0, sizeof(TkPattern)); /* Otherwise memcmp doesn't work. */

    /*
     * Handle simple ASCII characters.
     */

    if (*p != '<') {
	char string[2];
4968
4969
4970
4971
4972
4973
4974
4975

4976
4977
4978
4979
4980
4981
4982
4964
4965
4966
4967
4968
4969
4970

4971
4972
4973
4974
4975
4976
4977
4978







-
+







	    }
	    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 */
		    /* 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;
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
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







-
+









-
+







			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);
		    patPtr->modMask |= TkGetButtonMask(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->modMask |= TkGetButtonMask(button);
		    }
		    patPtr->info = ButtonNumberFromState(patPtr->modMask);
#endif
		} else {
		    return FinalizeParseEventDescription(
			    interp,
			    patPtr, 0,
5190
5191
5192
5193
5194
5195
5196
5197
5198


5199
5200
5201
5202
5203
5204
5205
5206


5207
5208
5209
5210
5211
5212
5213
5186
5187
5188
5189
5190
5191
5192


5193
5194
5195
5196
5197
5198
5199
5200


5201
5202
5203
5204
5205
5206
5207
5208
5209







-
-
+
+






-
-
+
+







			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));
		    assert(patPtr->info <= Button5);
		    Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) 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);
			Tcl_AppendPrintfToObj(patternObj, "-%u", button);
			mask &= ~TkGetButtonMask(button);
		    }
		    break;
		}
#endif
		}
	    }

5317
5318
5319
5320
5321
5322
5323





























5324
5325
5326
5327
5328
5329
5330
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    Tcl_Interp *interp)		/* Interpreter. */
{
    TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
    BindingTable *bindPtr = winPtr->mainPtr->bindingTable;

    return &bindPtr->curEvent->xev;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCancelWarp --
 *
 *	This function cancels an outstanding pointer warp and
 *	is called during tear down of the display.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpCancelWarp(
    TkDisplay *dispPtr)
{
    assert(dispPtr);

    if (dispPtr->flags & TK_DISPLAY_IN_WARP) {
	Tcl_CancelIdleCall(DoWarp, dispPtr);
	dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDumpPS --
 *
 *	Dump given pattern sequence to stdout.
Changes to generic/tkBitmap.c.
10
11
12
13
14
15
16




17
18
19
20
21
22
23
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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The includes below are for pre-defined bitmaps.
 *
 * Platform-specific issue: Windows complains when the bitmaps are included,
 * because an array of characters is being initialized with integers as
 * elements. For lint purposes, the following pragmas temporarily turn off
 * that warning message.
532
533
534
535
536
537
538
539

540
541
542
543
544
545
546
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);
    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	goto unknown;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    return bitmapPtr->nameHashPtr->key.string;
}

574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
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);
    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	goto unknownBitmap;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    *widthPtr = bitmapPtr->width;
    *heightPtr = bitmapPtr->height;
}
662
663
664
665
666
667
668
669

670
671
672
673
674
675
676
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);
    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument");
    }
    FreeBitmap((TkBitmap *)Tcl_GetHashValue(idHashPtr));
}

/*
830
831
832
833
834
835
836
837

838
839
840
841
842
843
844
834
835
836
837
838
839
840

841
842
843
844
845
846
847
848







-
+







    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);
	snprintf(string, sizeof(string), "_tk%d", dispPtr->bitmapAutoNumber);
	name = string;
	Tcl_SetHashValue(dataHashPtr, name);
	if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
	    Tcl_DeleteHashEntry(dataHashPtr);
	    return TCL_ERROR;
	}
    }
1010
1011
1012
1013
1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1028







-
+







				 * or NULL if unavailable. */
{
    Tcl_Interp *dummy;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * First initialize the data in the ThreadSpecificData strucuture, if
     * First initialize the data in the ThreadSpecificData structure, if
     * needed.
     */

    if (!tsdPtr->initialized) {
	tsdPtr->initialized = 1;
	dummy = Tcl_CreateInterp();
	Tcl_InitHashTable(&tsdPtr->predefBitmapTable, TCL_STRING_KEYS);
1074
1075
1076
1077
1078
1079
1080
1081

1082
1083
1084
1085
1086
1087
1088
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091
1092







-
+








/*
 *----------------------------------------------------------------------
 *
 * TkReadBitmapFile --
 *
 *	Loads a bitmap image in X bitmap format into the specified drawable.
 *	This is equivelent to the XReadBitmapFile in X.
 *	This is equivalent to the XReadBitmapFile in X.
 *
 * Results:
 *	Sets the size, hotspot, and bitmap on success.
 *
 * Side effects:
 *	Creates a new bitmap from the file data.
 *
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
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







-
+

-
+











-
+







	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_NewIntObj(bitmapPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(bitmapPtr->objRefCount));
		    Tcl_NewIntObj(bitmapPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetBitmapPredefTable --
 *
 *	This function is used by tkMacBitmap.c to access the thread-specific
 *	This function is used by tkMacOSXBitmap.c to access the thread-specific
 *	predefBitmap table that maps from the names of the predefined bitmaps
 *	to data associated with those bitmaps. It is required because the
 *	table is allocated in thread-local storage and is not visible outside
 *	this file.

 * Results:
 *	Returns a pointer to the predefined bitmap hash table for the current
Changes to generic/tkBusy.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
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55







+
+
+
+







-
+

















-
+







 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkBusy.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * 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),
	DEF_BUSY_CURSOR, -1, Tk_Offset(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 Tcl_FreeProc	DestroyBusy;
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,
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147







-
+







{
    Busy *busyPtr = (Busy *)clientData;

    Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);
    TkpHideBusyWindow(busyPtr);
    busyPtr->tkBusy = NULL;
    Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
    Tcl_EventuallyFree(busyPtr, DestroyBusy);
}

/*
 *----------------------------------------------------------------------
 *
 * BusyGeometryProc --
 *
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272







-
+







    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);
	Tcl_EventuallyFree(busyPtr, 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))) {
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+










-
+







 *	Memory and resources are released and the Tk event handler is removed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyBusy(
    void *data)			/* Busy window structure record */
    char *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_FreeConfigOptions((char *)data, busyPtr->optionTable, busyPtr->tkBusy);
	Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask,
		BusyEventProc, busyPtr);
	Tk_ManageGeometry(busyPtr->tkBusy, NULL, busyPtr);
	Tk_DestroyWindow(busyPtr->tkBusy);
    }
    ckfree(data);
}
375
376
377
378
379
380
381
382

383
384
385
386
387
388
389
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393







-
+







    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);
	Tcl_EventuallyFree(busyPtr, DestroyBusy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MakeTransparentWindowExist --
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
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







-
+



















-
+







	    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));
    snprintf(name, length + 6, 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,
    if (Tk_InitOptions(interp, (char *) busyPtr, busyPtr->optionTable,
	    tkBusy) != TCL_OK) {
	Tk_DestroyWindow(tkBusy);
	return NULL;
    }
    SetWindowInstanceData(tkBusy, busyPtr);
    winPtr = (Tk_FakeWin *) tkRef;

633
634
635
636
637
638
639
640

641
642
643
644
645
646
647
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651







-
+







    Tcl_Interp *interp,
    Busy *busyPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Cursor oldCursor = busyPtr->cursor;

    if (Tk_SetOptions(interp, busyPtr, busyPtr->optionTable, objc,
    if (Tk_SetOptions(interp, (char *) 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 {
678
679
680
681
682
683
684
685
686


687
688
689

690
691
692
693
694
695
696
682
683
684
685
686
687
688


689
690
691
692

693
694
695
696
697
698
699
700







-
-
+
+


-
+







    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) {
    tkwin = Tk_MainWindow(interp);
    if (!tkwin || (TkGetWindowFromObj(interp, tkwin, windowObj, &tkwin) != TCL_OK)) {
	return NULL;
    }
    hPtr = Tcl_FindHashEntry(busyTablePtr, tkwin);
    hPtr = Tcl_FindHashEntry(busyTablePtr, (char *) 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;
    }
735
736
737
738
739
740
741

742
743
744
745
746
747
748
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753







+







	    &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }
    hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew);
    if (isNew) {
	busyPtr = CreateBusy(interp, tkwin);
	if (busyPtr == NULL) {
	    Tcl_DeleteHashEntry(hPtr);
	    return TCL_ERROR;
	}
	Tcl_SetHashValue(hPtr, busyPtr);
	busyPtr->hashPtr = hPtr;
    } else {
	busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
    }
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
761
762
763
764
765
766
767



768
769
770
771
772
773
774







-
-
-







     */

    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 --
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
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







-
+
-


-
-
+
+



-
+









-
+










-
-
-
-
-
-
-
-
-
-
-
-
-










-
+











-
+








-
+







{
    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",
	"cget", "configure", "current", "forget", "hold", "status", NULL
        "status", NULL
    };
    enum options {
	BUSY_BUSYWINDOW, BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET,
	BUSY_HOLD, BUSY_STATUS
	BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, BUSY_HOLD,
	BUSY_STATUS
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "options ?arg ...?");
	Tcl_WrongNumArgs(interp, 1, objv, "options ?arg 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 ...?");
	    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,
	objPtr = Tk_GetOptionValue(interp, (char *) 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 ...?");
	    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,
	    objPtr = Tk_GetOptionInfo(interp, (char *)busyPtr,
		    busyPtr->optionTable, (objc == 4) ? objv[3] : NULL,
		    busyPtr->tkBusy);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
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
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







-
+
















-
+




-
+







	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));
			TkNewWindowObj(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);
	Tcl_EventuallyFree(busyPtr, DestroyBusy);
	return TCL_OK;

    case BUSY_HOLD:
	if (objc < 3 || objc%2 != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	    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");
Changes to generic/tkButton.c.
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42

43
44
45

46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76

77
78
79

80
81

82
83
84

85
86

87
88

89
90
91
92


93
94
95


96
97

98
99
100
101
102


103
104

105
106

107
108

109
110

111
112
113
114


115
116

117
118
119
120
121


122
123

124
125
126

127
128
129


130
131
132


133
134

135
136
137


138
139

140
141
142

143
144

145
146
147

148
149

150
151
152


153
154
155
156
157
158

159
160
161

162
163
164

165
166

167
168
169

170
171

172
173

174
175
176
177


178
179

180
181
182
183


184
185

186
187
188
189


190
191
192
193


194
195

196
197

198
199

200
201

202
203
204
205


206
207

208
209
210
211
212


213
214

215
216
217

218
219

220
221
222
223


224
225
226


227
228

229
230
231

232
233
234

235
236
237
238


239
240

241
242
243

244
245

246
247
248

249
250

251
252
253
254



255
256
257
258
259

260
261
262

263
264
265

266
267

268
269
270

271
272

273
274

275
276
277
278


279
280

281
282
283
284


285
286

287
288
289
290
291


292
293

294
295

296
297

298
299

300
301
302
303


304
305

306
307
308
309
310


311
312

313
314
315

316
317

318
319

320
321

322
323

324
325
326


327
328
329


330
331
332


333
334

335
336

337
338
339

340
341
342
343


344
345

346
347
348

349
350

351
352
353

354
355
356

357
358

359
360

361
362
363

364
365
366
367



368
369
370
371
372

373
374
375

376
377
378

379
380

381
382
383

384
385

386
387

388
389
390
391


392
393

394
395
396
397


398
399

400
401
402
403
404


405
406

407
408

409
410

411
412

413
414
415
416


417
418

419
420
421
422
423


424
425

426
427
428

429
430
431

432
433

434
435

436
437
438
439


440
441
442


443
444

445
446

447
448
449

450
451
452
453


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
25
26
27
28
29
30
31

32










33
34
35

36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66

67
68
69

70
71

72
73
74

75
76

77
78

79
80
81


82
83
84


85
86
87

88
89
90
91


92
93
94

95
96

97
98

99
100

101
102
103


104
105
106

107
108
109
110


111
112
113

114
115
116

117
118


119
120
121


122
123
124

125
126


127
128
129

130
131
132

133
134

135
136
137

138
139

140
141


142
143
144
145
146
147
148

149
150
151

152
153
154

155
156

157
158
159

160
161

162
163

164
165
166


167
168
169

170
171
172


173
174
175

176
177
178


179
180
181
182


183
184
185

186
187

188
189

190
191

192
193
194


195
196
197

198
199
200
201


202
203
204

205
206
207

208
209

210
211
212


213
214
215


216
217
218

219
220
221

222
223
224

225
226
227


228
229
230

231
232
233

234
235

236
237
238

239
240

241
242



243
244
245
246
247
248
249

250
251
252

253
254
255

256
257

258
259
260

261
262

263
264

265
266
267


268
269
270

271
272
273


274
275
276

277
278
279
280


281
282
283

284
285

286
287

288
289

290
291
292


293
294
295

296
297
298
299


300
301
302

303
304
305

306
307

308
309

310
311

312
313

314
315


316
317
318


319
320
321


322
323
324

325
326

327
328
329

330
331
332


333
334
335

336
337
338

339
340

341
342
343

344
345
346

347
348

349
350

351
352
353

354
355



356
357
358
359
360
361
362

363
364
365

366
367
368

369
370

371
372
373

374
375

376
377

378
379
380


381
382
383

384
385
386


387
388
389

390
391
392
393


394
395
396

397
398

399
400

401
402

403
404
405


406
407
408

409
410
411
412


413
414
415

416
417
418

419
420
421

422
423

424
425

426
427
428


429
430
431


432
433
434

435
436

437
438
439

440
441
442


443
444
445

446
447
448

449
450

451
452
453

454
455
456

457
458

459
460

461
462

463
464
465

466
467



468
469
470
471
472
473
474
475
476
477







-
+
-
-
-
-
-
-
-
-
-
-
+


-
+








-
+


















-
+


-
+


-
+

-
+


-
+

-
+

-
+


-
-
+
+

-
-
+
+

-
+



-
-
+
+

-
+

-
+

-
+

-
+


-
-
+
+

-
+



-
-
+
+

-
+


-
+

-
-
+
+

-
-
+
+

-
+

-
-
+
+

-
+


-
+

-
+


-
+

-
+

-
-
+
+





-
+


-
+


-
+

-
+


-
+

-
+

-
+


-
-
+
+

-
+


-
-
+
+

-
+


-
-
+
+


-
-
+
+

-
+

-
+

-
+

-
+


-
-
+
+

-
+



-
-
+
+

-
+


-
+

-
+


-
-
+
+

-
-
+
+

-
+


-
+


-
+


-
-
+
+

-
+


-
+

-
+


-
+

-
+

-
-
-
+
+
+




-
+


-
+


-
+

-
+


-
+

-
+

-
+


-
-
+
+

-
+


-
-
+
+

-
+



-
-
+
+

-
+

-
+

-
+

-
+


-
-
+
+

-
+



-
-
+
+

-
+


-
+

-
+

-
+

-
+

-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
+

-
+


-
+


-
-
+
+

-
+


-
+

-
+


-
+


-
+

-
+

-
+


-
+

-
-
-
+
+
+




-
+


-
+


-
+

-
+


-
+

-
+

-
+


-
-
+
+

-
+


-
-
+
+

-
+



-
-
+
+

-
+

-
+

-
+

-
+


-
-
+
+

-
+



-
-
+
+

-
+


-
+


-
+

-
+

-
+


-
-
+
+

-
-
+
+

-
+

-
+


-
+


-
-
+
+

-
+


-
+

-
+


-
+


-
+

-
+

-
+

-
+


-
+

-
-
-
+
+
+







 * Class names for buttons, indexed by one of the type values defined in
 * tkButton.h.
 */

static const char *const classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};

/*
 * The following table defines the legal values for the -default option. It is
 * The following table defines the legal values for the -default/-state options.
 * used together with the "enum defaultValue" declaration in tkButton.h.
 */

static const char *const defaultStrings[] = {
    "active", "disabled", "normal", NULL
};

/*
 * The following table defines the legal values for the -state option.
 * It is used together with the "enum state" declaration in tkButton.h.
 * It is used together with the "enum defaultValue/state" declarations in tkButton.h.
 */

static const char *const stateStrings[] = {
const char *const tkStateStrings[] = {
    "active", "disabled", "normal", NULL
};

/*
 * The following table defines the legal values for the -compound option.
 * It is used with the "enum compound" declaration in tkButton.h
 */

static const char *const compoundStrings[] = {
const char *const tkCompoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

char tkDefButtonHighlightWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_HIGHLIGHT_WIDTH;
char tkDefButtonPadx[TCL_INTEGER_SPACE] = DEF_BUTTON_PADX;
char tkDefButtonPady[TCL_INTEGER_SPACE] = DEF_BUTTON_PADY;
char tkDefButtonBorderWidth[TCL_INTEGER_SPACE] = DEF_BUTTON_BORDER_WIDTH;
char tkDefLabelHighlightWidth[TCL_INTEGER_SPACE] = DEF_LABEL_HIGHLIGHT_WIDTH;
char tkDefLabelPadx[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADX;
char tkDefLabelPady[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADY;

/*
 * Information used for parsing configuration options.  There is a
 * separate table for each of the four widget classes.
 */

static const Tk_OptionSpec labelOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(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),
	DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(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},
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, 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,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
	DEF_LABEL_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 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},
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefLabelHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
	tkDefLabelPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
	DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_LABEL_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	DEF_LABEL_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
	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, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(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),
	DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(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},
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	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},
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, 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, TCL_INDEX_NONE, offsetof(TkButton, defaultState),
	0, defaultStrings, 0},
	DEF_BUTTON_DEFAULT, -1, Tk_Offset(TkButton, defaultState),
	TK_OPTION_ENUM_VAR, tkStateStrings, 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},
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
	DEF_BUTTON_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 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},
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefButtonPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
	tkDefButtonPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefButtonPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
	tkDefButtonPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief),
	DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, relief),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	 DEF_BUTTON_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkButton, repeatDelay),
	 DEF_BUTTON_REPEAT_DELAY, -1, Tk_Offset(TkButton, repeatDelay),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	 DEF_BUTTON_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkButton, repeatInterval),
	 DEF_BUTTON_REPEAT_INTERVAL, -1, Tk_Offset(TkButton, repeatInterval),
	 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 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}
	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, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(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),
	DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(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},
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	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},
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, 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,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
	DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 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},
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn), 0, 0, 0},
	DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
	DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "Value",
	DEF_BUTTON_OFF_VALUE, offsetof(TkButton, offValuePtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_OFF_VALUE, Tk_Offset(TkButton, offValuePtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "Value",
	DEF_BUTTON_ON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_ON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 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},
	DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
	tkDefLabelPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
	DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(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,
	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, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
	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},
	DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_CHECKBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	DEF_CHECKBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 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}
	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, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(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),
	DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(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},
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	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},
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, 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,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
	DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 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},
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn),
	DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
	 DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
	tkDefLabelPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
	DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(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,
	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, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
	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},
	DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-value", "value", "Value",
	DEF_BUTTON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_RADIOBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	DEF_RADIOBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1,
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 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}
	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.
 */

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
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







-
+












-







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ButtonCreate(
    ClientData dummy,	/* NULL. */
    TCL_UNUSED(void *),	/* 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) {
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
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







-
+









-
+







    butPtr->commandPtr = NULL;
    butPtr->flags = 0;

    Tk_CreateEventHandler(butPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ButtonEventProc, butPtr);

    if (Tk_InitOptions(interp, butPtr, optionTable, tkwin)
    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_SetObjResult(interp, Tk_NewWindowObj(butPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(butPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonWidgetCmd --
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
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







-
+









-
+








    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,
	objPtr = Tk_GetOptionValue(interp, (char *) 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,
	    objPtr = Tk_GetOptionInfo(interp, (char *) butPtr,
		    butPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    butPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
1071
1072
1073
1074
1075
1076
1077
1078

1079
1080
1081
1082
1083
1084
1085
1061
1062
1063
1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1075







-
+








    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, butPtr,
	    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
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
1127







-
+







	}

	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);
			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,
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
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







-
-









-
+






-
+







    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;
	    void *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) {
		if (probe == (void *)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
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
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







-
-


















-
+






-
+







    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;
	    void *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) {
		if (probe == (void *)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
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1803
1804
1805
1806
1807
1808
1809






1810
1811
1812
1813
1814
1815
1816







-
-
-
-
-
-







    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;
	}
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1841
1842
1843
1844
1845
1846
1847






1848
1849
1850
1851
1852
1853
1854







-
-
-
-
-
-







    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
    /*
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1888
1889
1890
1891
1892
1893
1894






1895
1896
1897
1898
1899
1900
1901







-
-
-
-
-
-







    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
    /*
Changes to generic/tkButton.h.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkButton.h --
 *
 *	Declarations of types and functions used to implement button-like
 *	widgets.
 *
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 * Copyright (c) 1996-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 _TKBUTTON
#define _TKBUTTON
Changes to generic/tkCanvArc.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
10
11
12
13
14
15
16


17
18
19
20
21
22
23







-
-







 * 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
} 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
59
60
61
62
63
64
65






66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84

85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110

111
112

113
114

115
116

117
118

119
120
121

122
123
124

125
126

127
128
129

130
131

132
133

134
135

136
137

138
139
140

141
142

143


144

145
146
147

148
149

150
151
152

153
154

155
156

157
158

159
160

161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185







-
-
-
-
-
-

















-
+

-
+








-
+













-
+


-
+

-
+

-
+

-
+

-
+


-
+


-
+

-
+


-
+

-
+

-
+

-
+

-
+


-
+

-
+
-
-

-
+


-
+

-
+


-
+

-
+

-
+

-
+

-
+




-
+












-







    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);
		    char *widgRec, int offset);
static const char * StylePrintProc(ClientData clientData, Tk_Window tkwin,
		    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr);
		    char *widgRec, int 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
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, 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),
	NULL, Tk_Offset(ArcItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(ArcItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(ArcItem, outline.activeWidth),
	"0.0", Tk_Offset(ArcItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.dash),
	NULL, Tk_Offset(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},
	"0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledDash),
	NULL, Tk_Offset(ArcItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(ArcItem, outline.disabledWidth),
	"0.0", Tk_Offset(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},
	"90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(ArcItem, fillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(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),
	"0,0", Tk_Offset(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},
	DEF_CANVITEM_OUTLINE, Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(ArcItem, outline.tsoffset),
	"0,0", Tk_Offset(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},
	NULL, Tk_Offset(ArcItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-start", NULL, NULL,
	"0", offsetof(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(ArcItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-style", NULL, NULL,
	NULL, offsetof(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
	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", offsetof(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT,
	"1.0", Tk_Offset(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,
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
202
203
204
205
206
207
208


209
210
211
212
213
214
215







-
-







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 = {
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
229
230
231
232
233
234
235


236
237
238
239
240
241
242
243







-
-
+







    TranslateArc,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateArc,			/* rotateProc */
    0, NULL, NULL
    NULL, 0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateArc --
 *
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
288
289
290
291
292
293
294

295
296
297
298
299
300
301







-







    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]);
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377











378
379
380
381
382
383
384







-
+








-
-
-
-
-
-
-
-
-
-
-







			"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)
		    &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;
    }
470
471
472
473
474
475
476
477
478
479
480
481
482
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
444
445
446
447
448
449
450
















451
452
453
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
















+
+
+
+
+
+
+
+







	    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);
    }

    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 {
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
552
553
554
555
556
557
558

































































































559
560
561
562
563
564
565







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[3] + 0.5);
    }

    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
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
1375
1376
1377
1378
1379
1380
1381






















































1382
1383
1384
1385
1386
1387
1388







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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.
 *
2079
2080
2081
2082
2083
2084
2085
2086



2087
2088
2089
2090
2091
2092
2093



2094
2095
2096
2097
2098
2099
2100
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







-
+
+
+






-
+
+
+







	    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);
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
		goto error;
	    }
	    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);
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
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







-
+
+
+












-
+
+
+






-
+
+
+











-
+
+
+






-
+
+
+















+
+
+
+
+







		(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);
	if (Tk_CanvasPsOutline(canvas, itemPtr, &arcPtr->outline) != TCL_OK) {
	    goto error;
	}
	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);
		if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
		    goto error;
		}
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

		if (stipple != None) {
		    Tcl_AppendToObj(psObj, "clip ", -1);

		    Tcl_ResetResult(interp);
		    Tk_CanvasPsStipple(interp, canvas, stipple);
		    if (Tk_CanvasPsStipple(interp, canvas, stipple) !=TCL_OK){
			goto error;
		    }
		    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);
	    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (stipple != None) {
		Tcl_AppendToObj(psObj, "clip ", -1);

		Tcl_ResetResult(interp);
		Tk_CanvasPsStipple(interp, canvas, stipple);
		if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		    goto error;
		}
		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;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * StyleParseProc --
 *
2194
2195
2196
2197
2198
2199
2200
2201

2202
2203
2204
2205
2206
2207
2208
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2042







-
+







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 offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Style *stylePtr = (Style *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*stylePtr = PIESLICE_STYLE;
2255
2256
2257
2258
2259
2260
2261
2262

2263
2264
2265
2266
2267
2268
2269
2089
2090
2091
2092
2093
2094
2095

2096
2097
2098
2099
2100
2101
2102
2103







-
+







 */

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. */
    int 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) {
Changes to generic/tkCanvBmap.c.
41
42
43
44
45
46
47
48

49
50
51
52
53

54
55

56
57

58
59

60
61

62
63

64
65

66
67
68

69
70
71

72
73
74

75
76

77
78
79
80
81
82
83
41
42
43
44
45
46
47

48
49
50
51
52

53
54

55
56

57
58

59
60

61
62

63
64

65
66
67

68
69
70

71
72
73

74
75

76
77
78
79
80
81
82
83







-
+




-
+

-
+

-
+

-
+

-
+

-
+

-
+


-
+


-
+


-
+

-
+







 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activebackground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeforeground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"center", Tk_Offset(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-background", NULL, NULL,
	NULL, offsetof(BitmapItem, bgColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapItem, bgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-bitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, bitmap), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapItem, bitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledbackground", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledBgColor),
	NULL, Tk_Offset(BitmapItem, disabledBgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledbitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledBitmap),
	NULL, Tk_Offset(BitmapItem, disabledBitmap),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledforeground", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledFgColor),
	NULL, Tk_Offset(BitmapItem, disabledFgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-foreground", NULL, NULL,
	DEF_CANVBMAP_FG, offsetof(BitmapItem, fgColor), 0, NULL},
	DEF_CANVBMAP_FG, Tk_Offset(BitmapItem, fgColor), 0, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK,
	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, NULL}
};

/*
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
102
103
104
105
106
107
108


109
110
111
112
113
114
115







-
-







			    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);

/*
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
134
135
136
137
138
139
140


141
142
143
144
145
146
147
148







-
-
+







    TranslateBitmap,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateBitmap,		/* rotateProc */
    0, NULL, NULL
    NULL, 0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * TkcCreateBitmap --
 *
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
415
416
417
418
419
420
421

422
423
424
425
426
427
428







-







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);
    }
470
471
472
473
474
475
476

477
478
479
480
481
482
483
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480







+







 *
 * 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;
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686







+








-







 *
 * 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;
    (void)canvas;

    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
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744







+









-







 *
 * 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;
    (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;
    }
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
781
782
783
784
785
786
787

































788
789
790
791
792
793
794







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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 --
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
853
854
855
856
857
858
859

860
861
862
863
864
865
866







-







    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;
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
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







-
+
+
+














-
+
+
+







    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);
	if (Tk_CanvasPsColor(interp, canvas, bgColor) != TCL_OK) {
	    goto error;
	}
	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);
	if (Tk_CanvasPsColor(interp, canvas, fgColor) != TCL_OK) {
	    goto error;
	}
	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);
1006
1007
1008
1009
1010
1011
1012
1013
1014




1015
1016
1017
1018
1019
1020
1021
973
974
975
976
977
978
979


980
981
982
983
984
985
986
987
988
989
990







-
-
+
+
+
+







	    }

	    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);
	    if (Tk_CanvasPsBitmap(interp, canvas, bitmap,
		    0, curRow, width, rowsThisTime) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    Tcl_AppendToObj(psObj, "\n} imagemask\n", -1);
	}
    }

    /*
Changes to generic/tkCanvImg.c.
43
44
45
46
47
48
49
50

51
52
53
54
55

56
57

58
59

60
61

62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78


79
80
81
82
83
84
85
86
87
88


89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
43
44
45
46
47
48
49

50
51
52
53
54

55
56

57
58

59
60

61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
84
85
86


87
88
89
90

91
92
93
94
95
96


97
98
99
100
101
102
103







-
+




-
+

-
+

-
+

-
+

-
+













-
-
+
+








-
-
+
+


-
+





-
-







 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-activeimage", NULL, NULL,
	NULL, offsetof(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_STRING, "-disabledimage", NULL, NULL,
	NULL, offsetof(ImageItem, disabledImageString), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ImageItem, disabledImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-image", NULL, NULL,
	NULL, offsetof(ImageItem, imageString), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
	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, 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[]);
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[]);
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);
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const argv[]);
			    int objc, Tcl_Obj *const objv[]);
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);

/*
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
122
123
124
125
126
127
128


129
130
131
132
133
134
135
136







-
-
+







    TranslateImage,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateImage,		/* rotateProc */
    0, NULL, NULL
    NULL, 0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateImage --
 *
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263







-
+







			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)) {
		    &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);
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
378
379
380
381
382
383
384


385
386
387
388
389
390
391







-
-







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);
    }
422
423
424
425
426
427
428

429
430
431
432
433
434
435
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431







+







 *
 * 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;
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
530
531
532
533
534
535
536

537
538
539
540
541
542
543







-







				/* 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) {
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
588
589
590
591
592
593
594

595
596
597
598
599
600
601







-







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;

    /*
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
645
646
647
648
649
650
651

652
653
654
655
656
657
658







-







    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;
    }
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729







-
+







	}
    }
    if (image == NULL) {
	/*
	 * Image item without actual image specified.
	 */

        return TCL_OK;
	return TCL_OK;
    }
    Tk_SizeOfImage(image, &width, &height);

    /*
     * Compute the coordinates of the lower-left corner of the image, taking
     * into account the anchor position for the image.
     */
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
753
754
755
756
757
758
759


































760
761
762
763
764
765
766







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








	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.
888
889
890
891
892
893
894
895

896
897
898
899
900
901
902
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;
    ImageItem *imgPtr = 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
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27







-
+








+
+
+
+







/*
 * 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.
 * 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 "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The structure below defines the record for each line item.
 */

typedef enum {
    ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH
88
89
90
91
92
93
94
95

96
97
98
99
100

101
102

103
104
105
106
107
108
109
110
111

112
113

114
115
116
117

118
119

120
121
122
123
124
125
126
127
128
129
92
93
94
95
96
97
98

99
100
101
102
103

104
105

106
107
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 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);
			    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, TkSizeT first, TkSizeT last);
			    Tk_Item *itemPtr, int first, int last);
static void		LineInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
			    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, TkSizeT offset);
			    const char *value, char *recordPtr, int offset);
static const char * ArrowPrintProc(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    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, TkSizeT offset);
			    const char *value, char *recordPtr, int offset);
static const char * PrintArrowShape(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    Tk_Window tkwin, char *recordPtr, int 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);

/*
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166

167
168

169
170

171
172
173

174
175
176

177
178
179

180
181

182
183

184
185
186

187
188

189
190
191

192
193

194
195

196
197
198

199
200

201
202
203

204
205
206

207
208

209
210

211
212
213
214

215
216
217
218
219
220
221
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167

168
169

170
171

172
173
174

175
176
177

178
179
180

181
182

183
184

185
186
187

188
189

190
191
192

193
194

195
196

197
198
199

200
201

202
203
204

205
206
207

208
209

210
211

212
213
214
215

216
217
218
219
220
221
222
223







-
+














-
+


-
+

-
+

-
+


-
+


-
+


-
+

-
+

-
+


-
+

-
+


-
+

-
+

-
+


-
+

-
+


-
+


-
+

-
+

-
+



-
+







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
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, 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),
	NULL, Tk_Offset(LineItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(LineItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(LineItem, outline.activeWidth),
	"0.0", Tk_Offset(LineItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-arrow", NULL, NULL,
	"none", offsetof(LineItem, arrow),
	"none", Tk_Offset(LineItem, arrow),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowOption},
    {TK_CONFIG_CUSTOM, "-arrowshape", NULL, NULL,
	"8 10 3", offsetof(LineItem, arrowShapeA),
	"8 10 3", Tk_Offset(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},
	"butt", Tk_Offset(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},
	DEF_CANVITEM_OUTLINE, Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(LineItem, outline.dash),
	NULL, Tk_Offset(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},
	"0", Tk_Offset(LineItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledDash),
	NULL, Tk_Offset(LineItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(LineItem, outline.disabledWidth),
	"0.0", Tk_Offset(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},
	"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(LineItem, outline.tsoffset),
	"0,0", Tk_Offset(LineItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", offsetof(LineItem, smooth),
	"0", Tk_Offset(LineItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", offsetof(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(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),
	"1.0", Tk_Offset(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.
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
240
241
242
243
244
245
246


247
248
249
250
251
252
253
254







-
-
+







    TranslateLine,			/* translateProc */
    GetLineIndex,			/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    LineInsert,				/* insertProc */
    LineDeleteCoords,			/* dTextProc */
    NULL,				/* nextPtr */
    RotateLine,				/* rotateProc */
    0, NULL, NULL
    NULL, 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).
 */
695
696
697
698
699
700
701
702

703
704
705

706
707
708
709
710
711
712
696
697
698
699
700
701
702

703
704
705

706
707
708
709
710
711
712
713







-
+


-
+







	TkIncludePoint((Tk_Item *) linePtr, coordPtr);
    }
    width = linePtr->outline.width;
    if (width < 1.0) {
	width = 1.0;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	if (linePtr->arrow != ARROWS_LAST) {
	if (linePtr->arrow != ARROWS_LAST && linePtr->firstArrowPtr) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->firstArrowPtr);
	}
	if (linePtr->arrow != ARROWS_FIRST) {
	if (linePtr->arrow != ARROWS_FIRST && linePtr->lastArrowPtr) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr);
	}
    }

    tsoffset = &linePtr->outline.tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	coordPtr = linePtr->coordPtr
834
835
836
837
838
839
840
841

842
843
844
845
846
847
848
835
836
837
838
839
840
841

842
843
844
845
846
847
848
849







-
+







    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;
    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)) {
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
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







-
+




-
+












+

+
-
+


-
+


+
+
+
+
+
+









-
+















-
+








-
+




+
+




+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
















-
+









-
+

-
+







 *--------------------------------------------------------------
 */

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
    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;
    int length, oriNumPoints, objc, nbInsPoints, 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;
    }
    oriNumPoints = linePtr->numPoints;
    length = 2*linePtr->numPoints;
    nbInsPoints = objc / 2;
    if (beforeThis == TCL_INDEX_NONE) {
    if (beforeThis < 0) {
	beforeThis = 0;
    }
    if (beforeThis + 1 > (TkSizeT)length + 1) {
    if (beforeThis > length) {
	beforeThis = length;
    }

    /*
     * With arrows, the end points of the line are adjusted so that a thick
     * line doesn't stick out past the arrowheads (see ConfigureArrows).
     */

    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++) {
    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(Canvas(canvas)->interp);
	    ckfree(newCoordPtr);
	    return;
	}
    }

    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = linePtr->coordPtr[i];
    }
    if (linePtr->coordPtr) {
        ckfree(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
	 * 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 not set, the canvas will do the redrawing, otherwise I have
	 * to do it here.
	 * Rationale for the optimization code can be found in Tk ticket
	 * [5fb8145997].
	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;

	/*
	 * Include one point at left of the left insert position, and one
	 * point at right of the right insert position.
	 */
	if ((int)beforeThis > 0) {
	    beforeThis -= 2;
	    objc += 2;
	}
	if ((int)beforeThis+objc < length) {

	beforeThis -= 2;
	objc += 4;

	if (linePtr->smooth) {
	    objc += 2;
	}
	if (linePtr->smooth) {
	    if ((int)beforeThis > 0) {

	    if (!strcmp(linePtr->smooth->name, "true")) {
		/*
		 * Quadratic Bezier splines. A second point must be included at
		 * each side of the insert position.
		 */

		beforeThis -= 2;
		objc += 4;

		/*
		 * Moreover, if the insert position is the first or last point
		 * of the line, include a third point.
		 */

		if (beforeThis == -4) {
		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.
	     */
		    objc += 2;
		}
		if (beforeThis + 4 == length - (objc - 8)) {
		    beforeThis -= 2;
		    objc += 2;
		}

	    } else if (!strcmp(linePtr->smooth->name, "raw")) {
		/*
		 * Cubic Bezier splines. See details in ticket [5fb8145997].
		 */

		if (((oriNumPoints - 1) % 3) || (nbInsPoints % 3)) {
		    /*
		     * No optimization for "degenerate" lines or when inserting
		     * something else than a multiple of 3 points.
		     */

		    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
		} else {
		    beforeThis -= beforeThis % 6;
		    objc += 4;
		}

	    } else {
		/*
		 * Custom smoothing method. No optimization is possible.
		 */

		itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    }
	}

	if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	    if (beforeThis < 0) {
		beforeThis = 0;
	    }
	    if (beforeThis + objc > length) {
		objc = length - beforeThis;
	    }

	    itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis];
	    itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1];
	    if ((linePtr->firstArrowPtr != NULL) && (beforeThis < 2)) {
		/*
		 * Include old first arrow.
		 */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && ((int)beforeThis+objc >= length)) {
	    /*
	     * Include old last 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;
	}
    }
		for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
			i++, coordPtr += 2) {
		    TkIncludePoint(itemPtr, coordPtr);
		}
	    }
	    coordPtr = linePtr->coordPtr + beforeThis;
	    for (i=0; 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)) {
	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) && ((int)beforeThis+objc < length-2)) {
	if ((linePtr->lastArrowPtr != NULL) && (beforeThis+objc >= length)) {
	    /*
	     * Include new right arrow.
	     * Include new last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
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
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







-
-
+
+


-
+
+
+








-
+


-
+


-
-
+
+

-
+


+
+
+
+
+
+










+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
-
+







+
+















-
+







 *--------------------------------------------------------------
 */

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. */
    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 count, i, first1, last1, nbDelPoints;
    int oriNumPoints = linePtr->numPoints;
    int canOptimize = 1;
    int length = 2*linePtr->numPoints;
    double *coordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    first &= -2;
    first &= -2;	/* If odd, make it even. */
    last &= -2;

    if ((int)first < 0) {
    if (first < 0) {
	first = 0;
    }
    if ((int)last >= length) {
	last = length-2;
    if (last >= length) {
	last = length - 2;
    }
    if ((int)first > (int)last) {
    if (first > last) {
	return;
    }

    /*
     * With arrows, the end points of the line are adjusted so that a thick
     * line doesn't stick out past the arrowheads (see ConfigureArrows).
     */

    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];
    }
    first1 = first;
    last1 = last;
    nbDelPoints = (last - first) / 2 + 1;
    if (first1 > 0) {
	first1 -= 2;
    }
    if (last1 < length-2) {
	last1 += 2;
    }
    if (linePtr->smooth) {
	if (first1 > 0) {
	    first1 -= 2;
	}
	if (last1 < length-2) {
	    last1 += 2;
	}
    }

    /*
     * Include one point at left of the left delete position, and one
     * point at right of the right delete position.
     */

    first1 -= 2;
    last1 += 2;

    if (linePtr->smooth) {

	if (!strcmp(linePtr->smooth->name, "true")) {
	    /*
	     * Quadratic Bezier splines. A second point must be included at
	     * each side of the delete position.
	     */

	    first1 -= 2;
	    last1 += 2;

	    /*
	     * If the delete position is the first or last point of the line,
	     * include a third point.
	     */

	    if (first1 == -4) {
		last1 += 2;
	    }
	    if (last1 - 4 == length - 2) {
		first1 -= 2;
	    }

	} else if (!strcmp(linePtr->smooth->name, "raw")) {
	    /*
	     * Cubic Bezier splines. See details in ticket [5fb8145997].
	     */

	    if (((oriNumPoints - 1) % 3) || (nbDelPoints % 3)) {
		/*
		 * No optimization for "degenerate" lines or when deleting
		 * something else than a multiple of 3 points.
		 */

		canOptimize = 0;
	    }
	    else {
		first1 -= first1 % 6;
		last1 = last + 6 - last % 6;
	    }

	} else {
	    /*
	     * Custom smoothing method. No optimization is possible.
	     */

	    canOptimize = 0;
	}
    }

    if (first1 < 0) {
	first1 = 0;
    }
    if (last1 >= length) {
	last1 = length - 2;
    }

    if ((first1 >= 2) || (last1 < length-2)) {
    if (canOptimize && ((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.
	 * Rationale for the optimization code can be found in Tk ticket
	 * [5fb8145997].
	 */

	itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
	itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[first1];
	itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[first1+1];
	if ((linePtr->firstArrowPtr != NULL) && (first1 < 2)) {
	    /*
	     * Include old first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && (last1 >= length-2)) {
	if ((linePtr->lastArrowPtr != NULL) && (last1 >= length - 2)) {
	    /*
	     * Include old last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
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
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







-
+









-
+

-
+







    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }
    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && (first1 < 4)) {
	if ((linePtr->firstArrowPtr != NULL) && (first1 < 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) && (last1 > length-4)) {
	if ((linePtr->lastArrowPtr != NULL) && (last1 >= length - 2)) {
	    /*
	     * Include new right arrow.
	     * Include new last arrow.
	     */

	    for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
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
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







-
+

-

-
+
-

-
-
+
-
-
-
+
+

-
-
-
-
-
-
+
-
-
-
+
+







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. */
    int *indexPtr)		/* Where to store converted index. */
{
    TkSizeT idx, length;
    LineItem *linePtr = (LineItem *) itemPtr;
    const char *string;
    const char *string = Tcl_GetString(obj);
    (void)canvas;

    if (TCL_OK == TkGetIntForIndex(obj, 2*linePtr->numPoints - 1, 0, &idx)) {
	if (idx == TCL_INDEX_NONE) {
    if (string[0] == 'e') {
	    idx = 0;
	} else if (idx > (2*(TkSizeT)linePtr->numPoints)) {
	    idx = 2*linePtr->numPoints;
	if (strncmp(string, "end", obj->length) == 0) {
	    *indexPtr = 2*linePtr->numPoints;
	} else {
	    idx &= (TkSizeT)-2;	/* If index is odd, make it even. */
	}
	*indexPtr = idx;
	return TCL_OK;
    }

	    goto badIndex;
    string = TkGetStringFromObj(obj, &length);

    if (string[0] == '@') {
	}
    } else if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
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
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







+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+
+
-
-







	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
	    goto badIndex;

	/*
	 * Some of the paths here leave messages in interp->result, so we have to
	 * clear it out before storing our own message.
	 */
	}
	*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;

    /*
     * 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;
  badIndex:
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "LINE", NULL);
    return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TranslateLine --
 *
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
1978
1979
1980
1981
1982
1983
1984


















































1985
1986
1987
1988
1989
1990
1991







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    }
    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
1927
1928
1929
1930
1931
1932
1933
1934

1935
1936
1937
1938
1939
1940
1941
1942

1943
1944
1945
1946
1947
1948
1949
2002
2003
2004
2005
2006
2007
2008

2009
2010
2011
2012
2013
2014
2015
2016

2017
2018
2019
2020
2021
2022
2023
2024







-
+







-
+







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
    int 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)) {
    if (offset != Tk_Offset(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;
1993
1994
1995
1996
1997
1998
1999
2000

2001
2002
2003
2004
2005
2006
2007

2008
2009
2010
2011
2012
2013
2014
2068
2069
2070
2071
2072
2073
2074

2075
2076
2077
2078
2079
2080
2081

2082
2083
2084
2085
2086
2087
2088
2089







-
+






-
+








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_UNUSED(int),			/* 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,
    snprintf(buffer, 120, "%.5g %.5g %.5g", linePtr->arrowShapeA,
	    linePtr->arrowShapeB, linePtr->arrowShapeC);
    *freeProcPtr = TCL_DYNAMIC;
    return buffer;
}

/*
 *--------------------------------------------------------------
2031
2032
2033
2034
2035
2036
2037
2038

2039
2040
2041
2042
2043
2044
2045
2106
2107
2108
2109
2110
2111
2112

2113
2114
2115
2116
2117
2118
2119
2120







-
+







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 offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*arrowPtr = ARROWS_NONE;
2096
2097
2098
2099
2100
2101
2102
2103

2104
2105
2106
2107
2108
2109
2110
2171
2172
2173
2174
2175
2176
2177

2178
2179
2180
2181
2182
2183
2184
2185







-
+







 */

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. */
    int 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) {
2362
2363
2364
2365
2366
2367
2368
2369



2370
2371
2372
2373
2374
2375



2376
2377
2378
2379
2380
2381
2382
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







-
+
+
+





-
+
+
+







	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);
	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);
	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;
    }

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
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







-
+
+
+










-
-
+
+
+
+





-
-
+
+
+
+











+
+
+
+
+







	style = 2;
    } else {
	style = 0;
    }
    Tcl_AppendPrintfToObj(psObj, "%d setlinejoin\n", style);

    Tcl_ResetResult(interp);
    Tk_CanvasPsOutline(canvas, itemPtr, &linePtr->outline);
    if (Tk_CanvasPsOutline(canvas, itemPtr, &linePtr->outline) != TCL_OK) {
	goto error;
    }
    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 (ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->firstArrowPtr, psObj) != TCL_OK) {
	    goto error;
	}
    }
    if (linePtr->lastArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr, psObj);
	if (ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr, psObj) != TCL_OK) {
	    goto error;
	}
    }

    /*
     * 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;
}

/*
 *--------------------------------------------------------------
 *
 * ArrowheadPostscript --
 *
2527
2528
2529
2530
2531
2532
2533
2534



2535
2536
2537
2538
2539
2540
2541
2617
2618
2619
2620
2621
2622
2623

2624
2625
2626
2627
2628
2629
2630
2631
2632
2633







-
+
+
+







    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);
	if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    } else {
	Tcl_AppendToObj(psObj, "fill\n", -1);
    }
    return TCL_OK;
}

Changes to generic/tkCanvPoly.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
101

102
103
104

105
106

107
108
109

110
111
112

113
114

115

116
117

118
119

120
121

122
123
124

125
126

127
128
129

130
131

132
133
134

135
136

137
138

139
140
141
142

143
144
145
146
147
148
149
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82

83
84

85
86

87
88
89

90
91

92
93
94

95
96
97

98
99
100

101
102
103

104
105

106
107
108

109
110
111

112
113

114
115
116
117

118
119

120
121

122
123
124

125
126

127
128
129

130
131

132
133
134

135
136

137
138

139
140
141
142

143
144
145
146
147
148
149
150







-
+














-
+


-
+

-
+

-
+


-
+

-
+


-
+


-
+


-
+


-
+

-
+


-
+


-
+

-
+

+

-
+

-
+

-
+


-
+

-
+


-
+

-
+


-
+

-
+

-
+



-
+







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
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, 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),
	NULL, Tk_Offset(PolygonItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeStipple),
	NULL, Tk_Offset(PolygonItem, outline.activeStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(PolygonItem, outline.activeWidth),
	"0.0", Tk_Offset(PolygonItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.dash),
	NULL, Tk_Offset(PolygonItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(PolygonItem, outline.offset),
	"0", Tk_Offset(PolygonItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledDash),
	NULL, Tk_Offset(PolygonItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledColor),
	NULL, Tk_Offset(PolygonItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledStipple),
	NULL, Tk_Offset(PolygonItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(PolygonItem, outline.disabledWidth),
	"0.0", Tk_Offset(PolygonItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    /* Remark: Default for -fill should be NULL, see [2860519]. Will be fixed in Tk 8.7 */
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(PolygonItem, fillColor), TK_CONFIG_NULL_OK, NULL},
	DEF_CANVITEM_OUTLINE, Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", offsetof(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(PolygonItem, tsoffset),
	"0,0", Tk_Offset(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},
	NULL, Tk_Offset(PolygonItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(PolygonItem, outline.tsoffset),
	"0,0", Tk_Offset(PolygonItem, outline.tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", offsetof(PolygonItem, smooth),
	"0", Tk_Offset(PolygonItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", offsetof(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(PolygonItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(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),
	"1.0", Tk_Offset(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:
 */
159
160
161
162
163
164
165
166

167
168
169
170
171

172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
160
161
162
163
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		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);
			    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, TkSizeT first, TkSizeT last);
			    Tk_Item *itemPtr, int first, int last);
static void		PolygonInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
			    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		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);

/*
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
206
207
208
209
210
211
212


213
214
215
216
217
218
219
220







-
-
+







    TranslatePolygon,			/* translateProc */
    GetPolygonIndex,	/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    PolygonInsert,		/* insertProc */
    PolygonDeleteCoords,		/* dTextProc */
    NULL,				/* nextPtr */
    RotatePolygon,			/* rotateProc */
    0, NULL, NULL
    NULL, 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).
 */
675
676
677
678
679
680
681
682

683
684
685
686
687
688
689
673
674
675
676
677
678
679

680
681
682
683
684
685
686
687







-
+







		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->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) {
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
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







-
+




-
+












+

+
-
+


-
+



-
+










-
+







 *--------------------------------------------------------------
 */

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
    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;
    int length, oriNumPoints, objc, nbInsPoints, 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;
    }
    oriNumPoints = polyPtr->numPoints - polyPtr->autoClosed;
    length = 2*(polyPtr->numPoints - polyPtr->autoClosed);
    nbInsPoints = objc / 2;
    while ((int)beforeThis > length) {
    while (beforeThis > length) {
	beforeThis -= length;
    }
    while ((int)beforeThis < 0) {
    while (beforeThis < 0) {
	beforeThis += length;
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + 2 + objc));
    for (i=0; i<(int)beforeThis; i++) {
    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(newCoordPtr);
	    return;
	}
    }

    for (i=(int)beforeThis; i<length; i++) {
    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = polyPtr->coordPtr[i];
    }
    if (polyPtr->coordPtr) {
	ckfree(polyPtr->coordPtr);
    }
    length += objc;
    polyPtr->coordPtr = newCoordPtr;
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
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







+
+


-
+













+


+

+
+
+
+
+
-
-
-
+
+
+
+
+
+
+

+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	/*
	 * 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.
	 * Rationale for the optimization code can be found in Tk ticket
	 * [5fb8145997].
	 */

    	double width;
	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) {
	    if (!strcmp(polyPtr->smooth->name, "true")) {
		/*
		 * Quadratic Bezier splines.
		 */

	    beforeThis -= 2;
	    objc += 4;
	}
		beforeThis -= 2;
		objc += 4;

	    } else if (!strcmp(polyPtr->smooth->name, "raw")) {
		/*
		 * Cubic Bezier splines.
		 */

		if ((oriNumPoints % 3) || (nbInsPoints % 3)) {
	/*
	 * Be careful; beforeThis could now be negative
	 */
		    /*
		     * No optimization for "degenerate" polygons or when inserting
		     * something else than a multiple of 3 points.
		     */

		    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
		} else {
		    beforeThis -= abs(beforeThis) % 6;
		    objc += 4;
		}

	    } else {
		/*
		 * Custom smoothing method. No optimization is possible.
		 */

		itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    }
	}

	if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	    /*
	     * 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);
	    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 (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);
}

/*
 *--------------------------------------------------------------
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
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







-
-
+
+





-
+


-
+


-
+


-
+







 *--------------------------------------------------------------
 */

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. */
    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 ((int)first >= length) {
    while (first >= length) {
	first -= length;
    }
    while ((int)first < 0) {
    while (first < 0) {
	first += length;
    }
    while ((int)last >= length) {
    while (last >= length) {
	last -= length;
    }
    while ((int)last < 0) {
    while (last < 0) {
	last += length;
    }

    first &= -2;
    last &= -2;

    count = last + 2 - first;
1209
1210
1211
1212
1213
1214
1215
1216

1217
1218
1219
1220
1221
1222
1223
1245
1246
1247
1248
1249
1250
1251

1252
1253
1254
1255
1256
1257
1258
1259







-
+







    }

    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++) {
	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);
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
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







-
+

-

-
+
-

-
-
-
+
+
-
-
-
-
+
-
-
-
+
+
-
-
-
+







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. */
    int *indexPtr)		/* Where to store converted index. */
{
    TkSizeT length, idx;
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    const char *string;
    const char *string = Tcl_GetString(obj);
    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;
    if (string[0] == 'e') {
	if (strncmp(string, "end", obj->length) != 0) {
	} else {
	    idx = (idx & (TkSizeT)-2) % count;
	}
	*indexPtr = idx;
	    goto badIndex;
	return TCL_OK;
    }

	}
	*indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed);
    string = TkGetStringFromObj(obj, &length);

    if (string[0] == '@') {
    } else if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	    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) {
	    *indexPtr = 0;
	} else if (*indexPtr > 0) {
	    *indexPtr = ((*indexPtr - 2) % count) + 2;
	} else {
	    *indexPtr = -((-(*indexPtr)) % count);
	}
    }
    return TCL_OK;

	/*
	 * Some of the paths here leave messages in interp->result, so we have to
	 * clear it out before storing our own message.
	 */
    /*
     * Some of the paths here leave messages in interp->result, so we have to
     * clear it out before storing our own message.
     */

    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "POLY", NULL);
	return TCL_ERROR;
  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 --
 *
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
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







-
+
+
+






-
+
+
+




















-
+
+
+






-
+
+
+







		width/2.0, width/2.0);

	/*
	 * Color it in.
	 */

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);
	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);
	    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		goto error;
	    }
	    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);
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "eoclip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "eofill\n", -1);
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
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







-
+
+
+












+
+
+
+
+









	    style = 2;
	} else {
	    style = 0;
	}
	Tcl_AppendPrintfToObj(psObj, "%d setlinejoin 1 setlinecap\n", style);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &polyPtr->outline);
	if (Tk_CanvasPsOutline(canvas, itemPtr, &polyPtr->outline) != TCL_OK){
	    goto error;
	}
	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;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkCanvPs.c.
90
91
92
93
94
95
96
97

98
99

100
101

102
103

104
105

106
107

108
109

110
111

112
113

114
115

116
117

118
119

120
121

122
123

124
125

126
127

128
129
130
131
132
133
134
90
91
92
93
94
95
96

97
98

99
100

101
102

103
104

105
106

107
108

109
110

111
112

113
114

115
116

117
118

119
120

121
122

123
124

125
126

127
128
129
130
131
132
133
134







-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+







/*
 * 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_Offset(TkPostscriptInfo, colorVar), 0, NULL},
    {TK_CONFIG_STRING, "-colormode", NULL, NULL,
	"", offsetof(TkPostscriptInfo, colorMode), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, colorMode), 0, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	"", offsetof(TkPostscriptInfo, fileName), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, fileName), 0, NULL},
    {TK_CONFIG_STRING, "-channel", NULL, NULL,
	"", offsetof(TkPostscriptInfo, channelName), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, channelName), 0, NULL},
    {TK_CONFIG_STRING, "-fontmap", NULL, NULL,
	"", offsetof(TkPostscriptInfo, fontVar), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, fontVar), 0, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"", offsetof(TkPostscriptInfo, height), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, height), 0, NULL},
    {TK_CONFIG_ANCHOR, "-pageanchor", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageAnchor), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, pageAnchor), 0, NULL},
    {TK_CONFIG_STRING, "-pageheight", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageHeightString), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, pageHeightString), 0, NULL},
    {TK_CONFIG_STRING, "-pagewidth", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageWidthString), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, pageWidthString), 0, NULL},
    {TK_CONFIG_STRING, "-pagex", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageXString), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, pageXString), 0, NULL},
    {TK_CONFIG_STRING, "-pagey", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageYString), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, pageYString), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-prolog", NULL, NULL,
	"", offsetof(TkPostscriptInfo, prolog), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, prolog), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-rotate", NULL, NULL,
	"", offsetof(TkPostscriptInfo, rotate), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, rotate), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"", offsetof(TkPostscriptInfo, width), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, width), 0, NULL},
    {TK_CONFIG_PIXELS, "-x", NULL, NULL,
	"", offsetof(TkPostscriptInfo, x), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, x), 0, NULL},
    {TK_CONFIG_PIXELS, "-y", NULL, NULL,
	"", offsetof(TkPostscriptInfo, y), 0, NULL},
	"", Tk_Offset(TkPostscriptInfo, y), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations for functions defined later in this file:
 */

153
154
155
156
157
158
159

160
161
162
163
164
165
166
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167







+







 *
 * 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
486
487
488
489
490
491
492
493

494
495
496
497
498
499
500
487
488
489
490
491
492
493

494
495
496
497
498
499
500
501







-
+







	/*
	 * Insert the prolog
	 */

	Tcl_AppendObjToObj(psObj, preambleObj);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
	    channelWriteFailed:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"problem writing postscript data to channel: %s",
			Tcl_PosixError(interp)));
		result = TCL_ERROR;
		goto cleanup;
	    }
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555







-
+







		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) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);
	    psObj = Tcl_NewObj();
	}
    }

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
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







-
+









-
+




















-
+







	}

	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));
		    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) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
		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) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
		goto channelWriteFailed;
	    }
	}
    }

    if (psInfo.chan == NULL) {
	Tcl_SetObjResult(interp, psObj);
899
900
901
902
903
904
905












906
907
908
909
910
911
912
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







+
+
+
+
+
+
+
+
+
+
+
+








    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);


    if (!imagePtr) {
	/*
	 * The XGetImage() function is apparently not implemented on this
	 * system. Just skip the pixels, the Postscript will still be
	 * syntactically correct.
	 */

	Tcl_AppendToObj(psObj, "<>", -1);
	return;
    }

    Tcl_AppendToObj(psObj, "<", -1);
    mask = 0x80;
    value = 0;
    charsInLine = 0;
    lastX = startX + width - 1;
    lastY = startY + height - 1;
    for (y = lastY; y >= startY; y--) {
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1202
1203
1204
1205
1206
1207
1208


1209
1210
1211
1212
1213
1214
1215







-
-







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(
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
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







-














-
+







    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.colors = 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;
Changes to generic/tkCanvText.c.
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
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
    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). */
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73
58
59
60
61
62
63
64


65
66
67
68
69
70
71
72
73







-
-
+
+







				 * 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. */
    int numChars;		/* Length of text in characters. */
    int 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. */
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98

99
100

101
102

103
104

105
106

107
108

109
110

111
112

113
114

115
116

117
118
119

120
121

122
123
124
125

126
127

128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151



152
153
154

155
156
157
158
159

160
161
162

163
164

165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97

98
99

100
101

102
103

104
105

106
107

108
109

110
111

112
113

114
115

116
117
118

119
120

121
122
123
124

125
126

127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148



149
150
151
152
153

154
155
156
157
158

159
160
161

162
163

164
165

166
167
168
169
170
171
172


173
174
175
176
177
178
179







-
+







-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+


-
+

-
+



-
+

-
+

-
+













-
+





-
-
-
+
+
+


-
+




-
+


-
+

-
+

-
+






-
-







 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, 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},
	NULL, Tk_Offset(TextItem, activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"center", Tk_Offset(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},
	"0.0", Tk_Offset(TextItem, angle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(TextItem, disabledColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(TextItem, disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(TextItem, disabledStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(TextItem, disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(TextItem, color), TK_CONFIG_NULL_OK, NULL},
	DEF_CANVITEM_OUTLINE, Tk_Offset(TextItem, color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_FONT, "-font", NULL, NULL,
	DEF_CANVTEXT_FONT, offsetof(TextItem, tkfont), 0, NULL},
	DEF_CANVTEXT_FONT, Tk_Offset(TextItem, tkfont), 0, NULL},
    {TK_CONFIG_JUSTIFY, "-justify", NULL, NULL,
	"left", offsetof(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"left", Tk_Offset(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(TextItem, tsoffset),
	"0,0", Tk_Offset(TextItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(TextItem, stipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(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_Offset(TextItem, text), 0, NULL},
    {TK_CONFIG_INT, "-underline", NULL, NULL,
	"-1", offsetof(TextItem, underline), 0, NULL},
	"-1", Tk_Offset(TextItem, underline), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", offsetof(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"0", Tk_Offset(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[]);
			    int objc, 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		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, TkSizeT *indexPtr);
			    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, TkSizeT index);
			    Tk_Item *itemPtr, int index);
static int		TextCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const objv[]);
			    int objc, Tcl_Obj *const objv[]);
static void		TextDeleteChars(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
			    Tk_Item *itemPtr, int first, int last);
static void		TextInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
			    Tk_Item *itemPtr, int 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.
 */
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
195
196
197
198
199
200
201


202
203
204
205
206
207
208
209







-
-
+







    TranslateText,		/* translateProc */
    GetTextIndex,		/* indexProc */
    SetTextCursor,		/* icursorProc */
    GetSelText,			/* selectionProc */
    TextInsert,			/* insertProc */
    TextDeleteChars,		/* dTextProc */
    NULL,			/* nextPtr */
    RotateText,			/* rotateProc */
    0, NULL, NULL
    NULL, 0, NULL, NULL
};

#define ROUND(d) ((int) floor((d) + 0.5))

/*
 *--------------------------------------------------------------
 *
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
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







-
+


-
+



-
+




-
+







     * 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) {
	if (textInfoPtr->selectFirst >= textPtr->numChars) {
	    textInfoPtr->selItemPtr = NULL;
	} else {
	    if (textInfoPtr->selectLast + 1 >= textPtr->numChars + 1) {
	    if (textInfoPtr->selectLast >= textPtr->numChars) {
		textInfoPtr->selectLast = textPtr->numChars - 1;
	    }
	    if ((textInfoPtr->anchorItemPtr == itemPtr)
		    && (textInfoPtr->selectAnchor + 1 >= textPtr->numChars + 1)) {
		    && (textInfoPtr->selectAnchor >= textPtr->numChars)) {
		textInfoPtr->selectAnchor = textPtr->numChars - 1;
	    }
	}
    }
    if (textPtr->insertPos + 1 >= textPtr->numChars + 1) {
    if (textPtr->insertPos >= textPtr->numChars) {
	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.
561
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
558
559
560
561
562
563
564

565
566
567
568
569

570
571
572
573
574
575
576







-
+




-







 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteText(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    TCL_UNUSED(Tk_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);
    }
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639







-
+








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;
    int 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;
    }

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
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







-
-









-
-
-
+
+
+
-

-
+



-
+
-
-
-

-
+









-
-
-
+
+
+
-

-
+



-
-
-
-
+

-
+







    }

    /*
     * 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:
    case TK_ANCHOR_SW:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:
	topY -= height / 2;
	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height / 2;
	    dy[i] = -height;
	}
	break;

    case TK_ANCHOR_SW:
    default:
    case TK_ANCHOR_S:
    case TK_ANCHOR_SE:
	topY -= height;
	for (i=0 ; i<4 ; i++) {
	    dy[i] = -height;
	    dy[i] = -height / 2;
	}
	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:
    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:
	leftX -= width / 2;
	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width / 2;
	    dx[i] = -width;
	}
	break;

    case TK_ANCHOR_NE:
    case TK_ANCHOR_E:
    case TK_ANCHOR_SE:
	leftX -= width;
    default:
	for (i=0 ; i<4 ; i++) {
	    dx[i] = -width;
	    dx[i] = -width / 2;
	}
	break;
    }

    textPtr->actualWidth = width;

    sinA = textPtr->sine;
798
799
800
801
802
803
804
805

806
807
808
809
810
811
812
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798







-
+







    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;
    int selFirstChar, selLastChar;
    short drawableX, drawableY;
    Pixmap stipple;
    Tk_State state = itemPtr->state;

    textPtr = (TextItem *) itemPtr;
    textInfoPtr = textPtr->textInfoPtr;

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
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







-
+







-
+


-
+







     * read-only.
     */

    if (stipple != None) {
	Tk_CanvasSetOffset(canvas, textPtr->gc, &textPtr->tsoffset);
    }

    selFirstChar = TCL_INDEX_NONE;
    selFirstChar = -1;
    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 ) {
	if (selLastChar > textPtr->numChars) {
	    selLastChar = textPtr->numChars - 1;
	}
	if (((int)selFirstChar >= 0) && (selFirstChar + 1 <= selLastChar + 1 )) {
	if ((selFirstChar >= 0) && (selFirstChar <= selLastChar)) {
	    int xFirst, yFirst, hFirst;
	    int xLast, yLast, wLast;

	    /*
	     * Draw a special background under the selection.
	     */

956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
942
943
944
945
946
947
948

949
950
951
952
953
954
955
956







-
+







     * 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 ((selFirstChar >= 0) && (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,
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
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







-
+





-
+




-
+



-
+


-
+


-
+







 *----------------------------------------------------------------------
 */

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
    int 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;
    int byteCount;
    char *newStr, *text;
    const char *string;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    string = TkGetStringFromObj(obj, &byteCount);
    string = Tcl_GetStringFromObj(obj, &byteCount);

    text = textPtr->text;

    if (index == TCL_INDEX_NONE) {
    if (index < 0) {
	index = 0;
    }
    if (index + 1 > textPtr->numChars + 1) {
    if (index > textPtr->numChars) {
	index = textPtr->numChars;
    }
    byteIndex = Tcl_UtfAtIndex(text, index) - text;
    byteIndex = TkUtfAtIndex(text, index) - text;
    byteCount = strlen(string);
    if (byteCount == 0) {
	return;
    }

    newStr = (char *)ckalloc(textPtr->numBytes + byteCount + 1);
    memcpy(newStr, text, byteIndex);
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
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







-
+


-
+



-
+



-
+








    /*
     * 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) {
	if (textInfoPtr->selectFirst >= index) {
	    textInfoPtr->selectFirst += charsAdded;
	}
	if (textInfoPtr->selectLast + 1 >= index + 1) {
	if (textInfoPtr->selectLast >= index) {
	    textInfoPtr->selectLast += charsAdded;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor + 1 >= index + 1)) {
		&& (textInfoPtr->selectAnchor >= index)) {
	    textInfoPtr->selectAnchor += charsAdded;
	}
    }
    if (textPtr->insertPos + 1 >= index + 1) {
    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
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







-
+

-
+








-
+


-
+


-
+




-
-
+
+

















-
+

-
+



-
+

-
+



-
+



-
+

-
+




-
+

-
+







 *--------------------------------------------------------------
 */

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
    int first,			/* Character index of first character to
				 * delete. */
    TkSizeT last)			/* Character index of last 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 ((int)first < 0) {
    if (first < 0) {
	first = 0;
    }
    if (last + 1 >= textPtr->numChars + 1) {
    if (last >= textPtr->numChars) {
	last = textPtr->numChars - 1;
    }
    if (first + 1 > last + 1) {
    if (first > last) {
	return;
    }
    charsRemoved = last + 1 - first;

    byteIndex = Tcl_UtfAtIndex(text, first) - text;
    byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved)
    byteIndex = TkUtfAtIndex(text, first) - text;
    byteCount = TkUtfAtIndex(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) {
	if (textInfoPtr->selectFirst > first) {
	    textInfoPtr->selectFirst -= charsRemoved;
	    if ((int)textInfoPtr->selectFirst + 1 < (int)first + 1) {
	    if (textInfoPtr->selectFirst < first) {
		textInfoPtr->selectFirst = first;
	    }
	}
	if (textInfoPtr->selectLast + 1 >= first + 1) {
	if (textInfoPtr->selectLast >= first) {
	    textInfoPtr->selectLast -= charsRemoved;
	    if (textInfoPtr->selectLast + 1 < first) {
	    if (textInfoPtr->selectLast < first - 1) {
		textInfoPtr->selectLast = first - 1;
	    }
	}
	if ((int)textInfoPtr->selectFirst + 1 > (int)textInfoPtr->selectLast + 1) {
	if (textInfoPtr->selectFirst > textInfoPtr->selectLast) {
	    textInfoPtr->selItemPtr = NULL;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor + 1 > first + 1)) {
		&& (textInfoPtr->selectAnchor > first)) {
	    textInfoPtr->selectAnchor -= charsRemoved;
	    if (textInfoPtr->selectAnchor + 1 < first + 1) {
	    if (textInfoPtr->selectAnchor < first) {
		textInfoPtr->selectAnchor = first;
	    }
	}
    }
    if (textPtr->insertPos + 1 > first + 1) {
    if (textPtr->insertPos > first) {
	textPtr->insertPos -= charsRemoved;
	if ((int)textPtr->insertPos + 1 < (int)first + 1) {
	if (textPtr->insertPos < first) {
	    textPtr->insertPos = first;
	}
    }
    ComputeTextBbox(canvas, textPtr);
    return;
}

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
1240
1241
1242
1243
1244
1245
1246

































1247
1248
1249
1250
1251
1252
1253







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	    (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.
 *
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
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







-
+



-
+


-
+

-
-
-
+
-
-
-
-
+
+
+
-
-
-
-
-
-
-
+







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
    int *indexPtr)		/* Where to store converted character
				 * index. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT length, idx;
    int length;
    int c;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    const char *string;
    const char *string = Tcl_GetStringFromObj(obj, &length);

    if (TCL_OK == TkGetIntForIndex(obj, textPtr->numChars - 1, 1, &idx)) {
	if (idx == TCL_INDEX_NONE) {
	    idx = 0;
    c = string[0];
	} else if (idx > textPtr->numChars) {
	    idx = textPtr->numChars;
	}
	*indexPtr = idx;

    if ((c == 'e') && (strncmp(string, "end", length) == 0)) {
	*indexPtr = textPtr->numChars;
	return TCL_OK;
    }

    string = TkGetStringFromObj(obj, &length);
    c = string[0];

    if ((c == 'i')
    } else 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));
1441
1442
1443
1444
1445
1446
1447






1448
1449
1450
1451
1452
1453
1454
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404







+
+
+
+
+
+







	    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 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:
1476
1477
1478
1479
1480
1481
1482
1483

1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1426
1427
1428
1429
1430
1431
1432

1433
1434
1435
1436
1437

1438
1439
1440
1441
1442
1443
1444
1445







-
+




-
+







 */

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
    int index)			/* Character index of character just before
				 * which cursor is to be positioned. */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    if (index == TCL_INDEX_NONE) {
    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
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







-
+



-
+


-
+




-
+




-
-
+
+



-
-
+
+

-
-
-




+
+
+
-
+







 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
static int
GetSelText(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing selection. */
    Tk_Item *itemPtr,		/* Text item containing selection. */
    TkSizeT offset,			/* Byte offset within selection of first
    int 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,
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT byteCount;
    int byteCount;
    char *text;
    const char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    if (((int)textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst + 1 > textInfoPtr->selectLast + 1)) {
    if ((textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst > textInfoPtr->selectLast)) {
	return 0;
    }
    text = textPtr->text;
    selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
    selStart = TkUtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = TkUtfAtIndex(selStart,
	    textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst);
    if (selEnd  <= selStart + offset) {
	return 0;
    }
    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }
    if (byteCount <= 0) {
	return 0;
    }
    memcpy(buffer, selStart + offset, byteCount);
    memcpy(buffer, selStart + offset, (size_t) byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
 *--------------------------------------------------------------
 *
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
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







-
+
+
+









-









-
+


-


+







    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (prepass != 0) {
	goto done;
    }

    Tcl_ResetResult(interp);
    Tk_CanvasPsColor(interp, canvas, color);
    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	goto error;
    }
    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;
    default: 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;
    default:                justify = "0";   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);
Changes to generic/tkCanvUtil.c.
9
10
11
12
13
14
15




16
17
18
19
20
21
22
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 "tkCanvas.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Structures defined only in this file.
 */

typedef struct SmoothAssocData {
    struct SmoothAssocData *nextPtr;
				/* Pointer to next SmoothAssocData. */
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
231
232
233
234
235
236
237

238
239
240
241
242
243


244
245
246
247
248
249
250







-
+





-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoord(
    Tcl_Interp *dummy,		/* Interpreter for error reporting. */
    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. */
{
    (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;
}
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
267
268
269
270
271
272
273

274
275
276
277
278
279


280
281
282
283
284
285
286







-
+





-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

int
Tk_CanvasGetCoordFromObj(
    Tcl_Interp *dummy,		/* Interpreter for error reporting. */
    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. */
{
    (void)dummy;

    return Tk_GetDoublePixelsFromObj(Canvas(canvas)->interp, Canvas(canvas)->tkwin, obj, doublePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_CanvasSetStippleOrigin --
398
399
400
401
402
403
404
405
406


407
408
409
410
411

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435

436
437
438
439
440
441
442
398
399
400
401
402
403
404


405
406
407
408
409
410

411
412
413
414
415
416



417
418
419
420
421
422
423
424
425
426
427
428
429

430
431

432
433
434
435
436
437
438
439







-
-
+
+




-
+





-
-
-













-
+

-
+







 *	The tags for a given item get replaced by those indicated in the value
 *	argument.
 *
 *--------------------------------------------------------------
 */

int
TkCanvasTagsParseProc(
    ClientData dummy,	/* Not used.*/
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. */
    TkSizeT offset)			/* Offset into item (ignored). */
    int 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) {
    if (itemPtr->tagSpace < argc) {
	newPtr = (Tk_Uid *)ckalloc(argc * sizeof(Tk_Uid));
	for (i = (int)itemPtr->numTags - 1; i >= 0; i--) {
	for (i = 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;
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
465
466
467
468
469
470
471


472
473
474
475

476
477
478
479
480
481



482
483
484
485
486
487
488







-
-
+
+


-
+





-
-
-







 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkCanvasTagsPrintProc(
    ClientData dummy,	/* Ignored. */
Tk_CanvasTagsPrintProc(
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Ignored. */
    int 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;
514
515
516
517
518
519
520
521

522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
508
509
510
511
512
513
514

515
516
517
518
519

520
521



522
523
524
525
526
527
528







-
+




-
+

-
-
-







 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkCanvasDashParseProc(
    ClientData dummy,	/* Not used.*/
    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. */
    TkSizeT offset)			/* Offset into item. */
    int offset)			/* Offset into item. */
{
    (void)dummy;
    (void)tkwin;

    return Tk_GetDash(interp, value, (Tk_Dash *) (widgRec+offset));
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashPrintProc --
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
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







-
+


-
+







-
-




-
+








-
+



-
+

-
+







 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkCanvasDashPrintProc(
    ClientData dummy,	/* Ignored. */
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset in 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, *p;
    int i = dash->number;
    (void)dummy;
    (void)tkwin;

    if (i < 0) {
	i = -i;
	*freeProcPtr = TCL_DYNAMIC;
	buffer = (char *)ckalloc(i + 1);
	buffer = 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);
    buffer = ckalloc(4 * i);
    *freeProcPtr = TCL_DYNAMIC;

    p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
    sprintf(buffer, "%d", *p++ & 0xff);
    snprintf(buffer, 4 * i, "%d", *p++ & 0xff);
    while (--i) {
	sprintf(buffer+strlen(buffer), " %d", *p++ & 0xff);
	snprintf(buffer + strlen(buffer), 4 * i - 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
602
603
604
605
606
607
608

609
610
611
612
613

614
615
616
617
618
619
620
621







-
+




-
+








static SmoothAssocData *
InitSmoothMethods(
    Tcl_Interp *interp)
{
    SmoothAssocData *methods, *ptr;

    methods = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    methods = 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 = methods->nextPtr = 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;
652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655







-
+








void
Tk_CreateSmoothMethod(
    Tcl_Interp *interp,
    const Tk_SmoothMethod *smooth)
{
    SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;
    methods = (SmoothAssocData *)Tcl_GetAssocData(interp, "smoothMethod", NULL);
    methods = Tcl_GetAssocData(interp, "smoothMethod", NULL);

    /*
     * Initialize if we were not previously initialized.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
678
679
680
681
682
683
684
685

686
687
688
689
690
691
692
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681







-
+







	    } else {
		prevPtr->nextPtr = typePtr2->nextPtr;
	    }
	    ckfree(typePtr2);
	    break;
	}
    }
    ptr = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    ptr = 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);
}

707
708
709
710
711
712
713
714

715
716

717
718
719
720
721
722
723
724
696
697
698
699
700
701
702

703
704

705

706
707
708
709
710
711
712







-
+

-
+
-







 *----------------------------------------------------------------------
 */

static void
SmoothMethodCleanupProc(
    ClientData clientData,	/* Points to "smoothMethod" AssocData for the
				 * interpreter. */
    Tcl_Interp *dummy)		/* Interpreter that is being deleted. */
    Tcl_Interp *interp)		/* Interpreter that is being deleted. */
{
    SmoothAssocData *ptr, *methods = (SmoothAssocData *)clientData;
    SmoothAssocData *ptr, *methods = clientData;
    (void)dummy;

    while (methods != NULL) {
	ptr = methods;
	methods = methods->nextPtr;
	ckfree(ptr);
    }
}
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
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







-
+




-
+







-
-






-
+










-
+







 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkSmoothParseProc(
    ClientData dummy,	/* Ignored. */
    ClientData clientData,	/* 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. */
    int 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);
    methods = Tcl_GetAssocData(interp, "smoothMethod", NULL);

    /*
     * Not initialized yet; fix that now.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
    }

    /*
     * Backward compatability hack.
     * Backward compatibility hack.
     */

    if (strncmp(value, "bezier", length) == 0) {
	smooth = &tkBezierSmoothMethod;
    }

    /*
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
818
819
820
821
822
823
824

825
826
827

828
829
830
831
832
833
834



835
836
837
838
839
840
841







-
+


-
+






-
-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkSmoothPrintProc(
    ClientData dummy,	/* Ignored. */
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    TkSizeT offset,			/* Offset into 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. */
{
    const Tk_SmoothMethod *smoothPtr =
	    * (Tk_SmoothMethod **) (widgRec + offset);
    (void)dummy;
	(void)tkwin;
    (void)freeProcPtr;

    return smoothPtr ? smoothPtr->name : "0";
}
/*
 *--------------------------------------------------------------
 *
 * Tk_GetDash
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
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







-
+

















-
+







    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));
	    dash->pattern.pt = pt = 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);
	dash->pattern.pt = pt = ckalloc(argc);
    } else {
	pt = dash->pattern.array;
    }
    dash->number = argc;

    largv = argv;
    while (argc > 0) {
1243
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254
1255
1256
1257
1226
1227
1228
1229
1230
1231
1232

1233
1234
1235
1236
1237
1238
1239
1240







-
+








    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);
	q = 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;
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279







+







	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
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
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







-
+




















-
+
+
+
+
+
+
+



-
+
+
+







	    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);
	    lptr = 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 (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Note that psObj might hold an invalid reference now.
     */

    if (stipple != None) {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "StrokeClip ", -1);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "stroke\n", -1);
    }

    return TCL_OK;
}

1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671
1672
1673
1674







-







    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.
     *
1729
1730
1731
1732
1733
1734
1735
1736

1737
1738
1739
1740
1741
1742
1743
1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733
1734







-
+







     * 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));
	tempArr = ckalloc(numVertex * 12 * sizeof(double));
    }
    for (i=0; i<numVertex*2; i++){
	tempArr[i] = coordArr[i];
    }
    a = tempArr;
    b = &tempArr[numVertex*6];

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
1863
1864
1865
1866
1867
1868
1869





































1870
1871
1872
1873
1874
1875
1876
1877







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








	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:
 */
Changes to generic/tkCanvWind.c.
37
38
39
40
41
42
43
44

45
46
47
48
49

50
51

52
53

54
55
56
57

58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
37
38
39
40
41
42
43

44
45
46
47
48

49
50

51
52

53
54
55
56

57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


80
81
82
83
84
85
86







-
+




-
+

-
+

-
+



-
+

-
+




















-
-







 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"0", offsetof(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
	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", offsetof(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
	"0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_WINDOW, "-window", NULL, NULL,
	NULL, offsetof(WindowItem, tkwin), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(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,
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
126
127
128
129
130
131
132


133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151







-
-
+










-
+







    TranslateWinItem,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateWinItem,		/* rotateProc */
    0, NULL, NULL
    NULL, 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 */
    WinItemLostContentProc,		/* lostSlaveProc */
};

/*
 *--------------------------------------------------------------
 *
 * CreateWinItem --
 *
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
401
402
403
404
405
406
407

408
409
410
411
412
413
414







-







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);
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
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







-
-
-
-
-




+
+
+














+







				 * 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;
    }

    Tcl_Preserve(canvas);

    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) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	Tcl_Release(canvas);
	return;
    }
    Tk_CanvasWindowCoords(canvas, (double) winItemPtr->header.x1,
	    (double) winItemPtr->header.y1, &x, &y);
    width = winItemPtr->header.x2 - winItemPtr->header.x1;
    height = winItemPtr->header.y2 - winItemPtr->header.y1;

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
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







+














+
+
-
+
+
+




+







    if (((x + width) <= 0) || ((y + height) <= 0)
	    || (x >= Tk_Width(canvasTkwin)) || (y >= Tk_Height(canvasTkwin))) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	Tcl_Release(canvas);
	return;
    }

    /*
     * Reposition and map the window (but in different ways depending on
     * whether the canvas is the window's parent).
     */

    if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
		|| (width != Tk_Width(winItemPtr->tkwin))
		|| (height != Tk_Height(winItemPtr->tkwin))) {
	    Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);
	}

	if (winItemPtr->tkwin) {
	Tk_MapWindow(winItemPtr->tkwin);
	    Tk_MapWindow(winItemPtr->tkwin);
	}

    } else {
	Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,
		width, height);
    }
    Tcl_Release(canvas);
}

/*
 *--------------------------------------------------------------
 *
 * WinItemToPoint --
 *
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
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;

    /*
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
718
719
720
721
722
723
724

725
726
727
728
729
730
731







-







    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;
    }
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770
771
772
773
774
754
755
756
757
758
759
760

761
762
763



764
765
766
767
768
769
770







-
+


-
-
-







 *
 *--------------------------------------------------------------
 */

#ifdef X_GetImage
static int
xerrorhandler(
    ClientData dummy,
    ClientData clientData,
    XErrorEvent *e)
{
    (void)dummy;
    (void)e;

    return 0;
}
#endif /* X_GetImage */

/*
 *--------------------------------------------------------------
 *
799
800
801
802
803
804
805
806

807
808
809
810
811
812
813
795
796
797
798
799
800
801

802
803
804
805
806
807
808
809







-
+







{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    double x, y;
    int width, height;
    Tk_Window tkwin = winItemPtr->tkwin;

    if (prepass || winItemPtr->tkwin == NULL) {
        return TCL_OK;
	return TCL_OK;
    }

    width = Tk_Width(tkwin);
    height = Tk_Height(tkwin);

    /*
     * Compute the coordinates of the lower-left corner of the window, taking
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
921
922
923
924
925
926
927


































928
929
930
931
932
933
934







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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 --
 *
 *	This function is invoked to rescale a window item.
 *
 * Results:
 *	None.
 *
1051
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025
1026
1027







-
+







 */

static void
WinItemStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    WindowItem *winItemPtr = clientData;

    if (eventPtr->type == DestroyNotify) {
	winItemPtr->tkwin = NULL;
    }
}

/*
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1096
1043
1044
1045
1046
1047
1048
1049

1050

1051
1052
1053
1054
1055
1056
1057







-
+
-







 */

static void
WinItemRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    WindowItem *winItemPtr = 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.
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121

1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
1133
1134
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086

1087
1088

1089
1090
1091
1092
1093
1094
1095







+


-
+



-
+

-







 *
 * Side effects:
 *	Forgets all canvas-related information about the content window.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
WinItemLostContentProc(
    ClientData clientData,	/* WindowItem structure for content window window that
    ClientData clientData,	/* WindowItem structure for content window that
				 * was stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    WindowItem *winItemPtr = 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);
Changes to generic/tkCanvas.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
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57









-
+





+
+
-
-
-
+
+
+










+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/*
 * tkCanvas.c --
 *
 *	This module implements canvas widgets for the Tk toolkit. A canvas
 *	displays a background and a collection of graphical objects such as
 *	rectangles, lines, and texts.
 *
 * 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.
 * 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.
 */

/* #define USE_OLD_TAG_SEARCH 1 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"
#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
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120

121
122
123
124
125

126
127

128
129

130
131

132
133

134
135
136

137
138

139
140
141

142
143

144
145
146

147
148
149

150
151

152
153

154
155

156
157

158
159
160

161
162

163
164
165

166
167
168

169
170
171
172

173
174

175
176
177

178
179
180

181
182
183

184
185
186

187
188
189

190
191

192
193
194
195

196
197
198

199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251


252
253
254
255
256
257
258

259
260
261
262
263


264
265
266
267


268
269




270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

287
288

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367







-
+


















+
+




















-
+


-
+




-
+

-
+

-
+

-
+

-
+


-
+

-
+


-
+

-
+


-
+


-
+

-
+

-
+

-
+

-
+


-
+

-
+


-
+


-
+



-
+

-
+


-
+


-
+


-
+


-
+


-
+

-
+



-
+


-
+



-
+














+




















+












-
-
+
+





-
+




-
-
+
+


-
-
+
+
-
-
-
-
+
-





+


+
+
+
+


+

-
+

-
+

+
+
+



+
+
+
+
+
+


-
+










+

















+
+
+
+
+
+
+
+
+
+
+















+







    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 */
    int 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 */

#endif /* USE_OLD_TAG_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),
	DEF_CANVAS_BG_COLOR, Tk_Offset(TkCanvas, bgBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_MONO, offsetof(TkCanvas, bgBorder),
	DEF_CANVAS_BG_MONO, Tk_Offset(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},
	DEF_CANVAS_BORDER_WIDTH, Tk_Offset(TkCanvas, borderWidth), 0, NULL},
    {TK_CONFIG_DOUBLE, "-closeenough", "closeEnough", "CloseEnough",
	DEF_CANVAS_CLOSE_ENOUGH, offsetof(TkCanvas, closeEnough), 0, NULL},
	DEF_CANVAS_CLOSE_ENOUGH, Tk_Offset(TkCanvas, closeEnough), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-confine", "confine", "Confine",
	DEF_CANVAS_CONFINE, offsetof(TkCanvas, confine), 0, NULL},
	DEF_CANVAS_CONFINE, Tk_Offset(TkCanvas, confine), 0, NULL},
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_CANVAS_CURSOR, offsetof(TkCanvas, cursor), TK_CONFIG_NULL_OK, NULL},
	DEF_CANVAS_CURSOR, Tk_Offset(TkCanvas, cursor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-height", "height", "Height",
	DEF_CANVAS_HEIGHT, offsetof(TkCanvas, height), 0, NULL},
	DEF_CANVAS_HEIGHT, Tk_Offset(TkCanvas, height), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_CANVAS_HIGHLIGHT_BG,
	offsetof(TkCanvas, highlightBgColorPtr), 0, NULL},
	Tk_Offset(TkCanvas, highlightBgColorPtr), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_CANVAS_HIGHLIGHT, offsetof(TkCanvas, highlightColorPtr), 0, NULL},
	DEF_CANVAS_HIGHLIGHT, Tk_Offset(TkCanvas, highlightColorPtr), 0, NULL},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_CANVAS_HIGHLIGHT_WIDTH, offsetof(TkCanvas, highlightWidth), 0, NULL},
	DEF_CANVAS_HIGHLIGHT_WIDTH, Tk_Offset(TkCanvas, highlightWidth), 0, NULL},
    {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_CANVAS_INSERT_BG, offsetof(TkCanvas, textInfo.insertBorder), 0, NULL},
	DEF_CANVAS_INSERT_BG, Tk_Offset(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_Offset(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_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_CANVAS_INSERT_OFF_TIME, offsetof(TkCanvas, insertOffTime), 0, NULL},
	DEF_CANVAS_INSERT_OFF_TIME, Tk_Offset(TkCanvas, insertOffTime), 0, NULL},
    {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_CANVAS_INSERT_ON_TIME, offsetof(TkCanvas, insertOnTime), 0, NULL},
	DEF_CANVAS_INSERT_ON_TIME, Tk_Offset(TkCanvas, insertOnTime), 0, NULL},
    {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_CANVAS_INSERT_WIDTH, offsetof(TkCanvas, textInfo.insertWidth), 0, NULL},
	DEF_CANVAS_INSERT_WIDTH, Tk_Offset(TkCanvas, textInfo.insertWidth), 0, NULL},
    {TK_CONFIG_CUSTOM, "-offset", "offset", "Offset", "0,0",
	offsetof(TkCanvas, tsoffset),TK_CONFIG_DONT_SET_DEFAULT,
	Tk_Offset(TkCanvas, tsoffset),TK_CONFIG_DONT_SET_DEFAULT,
	&offsetOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_CANVAS_RELIEF, offsetof(TkCanvas, relief), 0, NULL},
	DEF_CANVAS_RELIEF, Tk_Offset(TkCanvas, relief), 0, NULL},
    {TK_CONFIG_STRING, "-scrollregion", "scrollRegion", "ScrollRegion",
	DEF_CANVAS_SCROLL_REGION, offsetof(TkCanvas, regionString),
	DEF_CANVAS_SCROLL_REGION, Tk_Offset(TkCanvas, regionString),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_COLOR, offsetof(TkCanvas, textInfo.selBorder),
	DEF_CANVAS_SELECT_COLOR, Tk_Offset(TkCanvas, textInfo.selBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_MONO, offsetof(TkCanvas, textInfo.selBorder),
	DEF_CANVAS_SELECT_MONO, Tk_Offset(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_Offset(TkCanvas, textInfo.selBorderWidth), TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_MONO, offsetof(TkCanvas, textInfo.selBorderWidth),
	DEF_CANVAS_SELECT_BD_MONO, Tk_Offset(TkCanvas, textInfo.selBorderWidth),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_COLOR, offsetof(TkCanvas, textInfo.selFgColorPtr),
	DEF_CANVAS_SELECT_FG_COLOR, Tk_Offset(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),
	DEF_CANVAS_SELECT_FG_MONO, Tk_Offset(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,
	"normal", Tk_Offset(TkCanvas, canvas_state), TK_CONFIG_DONT_SET_DEFAULT,
	&stateOption},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_CANVAS_TAKE_FOCUS, offsetof(TkCanvas, takeFocus),
	DEF_CANVAS_TAKE_FOCUS, Tk_Offset(TkCanvas, takeFocus),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	DEF_CANVAS_WIDTH, offsetof(TkCanvas, width), 0, NULL},
	DEF_CANVAS_WIDTH, Tk_Offset(TkCanvas, width), 0, NULL},
    {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_CANVAS_X_SCROLL_CMD, offsetof(TkCanvas, xScrollCmd),
	DEF_CANVAS_X_SCROLL_CMD, Tk_Offset(TkCanvas, xScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-xscrollincrement", "xScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_X_SCROLL_INCREMENT, offsetof(TkCanvas, xScrollIncrement),
	DEF_CANVAS_X_SCROLL_INCREMENT, Tk_Offset(TkCanvas, xScrollIncrement),
	0, NULL},
    {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	DEF_CANVAS_Y_SCROLL_CMD, offsetof(TkCanvas, yScrollCmd),
	DEF_CANVAS_Y_SCROLL_CMD, Tk_Offset(TkCanvas, yScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-yscrollincrement", "yScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_Y_SCROLL_INCREMENT, offsetof(TkCanvas, yScrollIncrement),
	DEF_CANVAS_Y_SCROLL_INCREMENT, Tk_Offset(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)

#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 TkSizeT	CanvasFetchSelection(ClientData clientData, TkSizeT offset,
			    char *buffer, TkSizeT maxBytes);
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, TkSizeT index);
			    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);
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const *objv);
static void		CanvasWorldChanged(ClientData instanceData);
static int		ConfigureCanvas(Tcl_Interp *interp,
			    TkCanvas *canvasPtr, int argc,
			    Tcl_Obj *const *argv, int flags);
			    TkCanvas *canvasPtr, int objc,
			    Tcl_Obj *const *objv, int flags);
static void		DefaultRotateImplementation(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, double x, double y,
			    double angleRadians);
static void		DestroyCanvas(void *memPtr);
static Tcl_FreeProc	DestroyCanvas;
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);
#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 objc, Tcl_Obj *const *objv,
			    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);
			    Tcl_Obj *const *objv, Tk_Uid uid, int enclosed);
static double		GridAlign(double coord, double spacing);
static const char**	TkGetStringsFromObjs(int argc, Tcl_Obj *const *objv);
static const char**	TkGetStringsFromObjs(int objc, 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		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 const Tk_ClassProcs canvasClass = {
    sizeof(Tk_ClassProcs),	/* size */
    CanvasWorldChanged,		/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 * 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))
#define FIND_ITEMS(objPtr, n) \
    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n))
#define RELINK_ITEMS(objPtr, itemPtr) \
    RelinkItems(canvasPtr, (objPtr), (itemPtr))
#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)))
#define FIND_ITEMS(objPtr, n) \
    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n), &searchPtr)
#define RELINK_ITEMS(objPtr, itemPtr) \
    result = RelinkItems(canvasPtr, (objPtr), (itemPtr), &searchPtr)
#endif /* USE_OLD_TAG_SEARCH */

/*
 * ----------------------------------------------------------------------
 *
 * AlwaysRedraw, ItemConfigure, ItemCoords, etc. --
 *
 *	Helper functions that make access to canvas item functions simpler.
468
469
470
471
472
473
474
475

476
477
478
479
480
481
482
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532







-
+







}

static int
ItemIndex(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *objPtr,
    TkSizeT *indexPtr)
    int *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,
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
609
610
611
612
613
614
615
































































































616
617
618
619
620
621
622







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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
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
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







-
-
+
+









-
-
+
+



-
+







 *--------------------------------------------------------------
 */

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. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* 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 ...?");
    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    newWin = Tk_CreateWindowFromPath(interp,tkwin,Tcl_GetString(argv[1]),NULL);
    newWin = Tk_CreateWindowFromPath(interp,tkwin,Tcl_GetString(objv[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
721
722
723
724
725
726
727
728
729


730
731
732
733
734
735
736


737
738
739
740
741
742
743
675
676
677
678
679
680
681


682
683
684
685
686
687
688


689
690
691
692
693
694
695
696
697







-
-
+
+





-
-
+
+







    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->width = 0;
    canvasPtr->height = 0;
    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.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;
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
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







+

+













-
+



-
+







    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, 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) {
    if (ConfigureCanvas(interp, canvasPtr, objc-2, objv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(canvasPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(canvasPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(canvasPtr->tkwin);
    return TCL_ERROR;
}

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
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







+
+
+


+

-
-
+
+




-
-
+
+

-
-
-
+
+
+

-
+




-
-
+
+

-
-
+
+
-






-
-
+
+





-
+







    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 idx;
    static const char *const canvasOptionStrings[] = {
    int index;
    static const char *const optionStrings[] = {
	"addtag",	"bbox",		"bind",		"canvasx",
	"canvasy",	"cget",		"configure",	"coords",
	"create",	"dchars",	"delete",	"dtag",
	"find",		"focus",	"gettags",	"icursor",
        "image",	"imove",	"index",	"insert",
	"itemcget",	"itemconfigure",
	"imove",	"index",	"insert",	"itemcget",
	"itemconfigure",
	"lower",	"move",		"moveto",	"postscript",
	"raise",	"rchars",	"rotate",	"scale",
	"scan",		"select",	"type",		"xview",
	"yview",	NULL
	"raise",	"rchars",	"scale",	"scan",
	"select",	"type",		"xview",	"yview",
	NULL
    };
    enum canvasOptionStringsEnum {
    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_IMAGE,	CANV_IMOVE,	CANV_INDEX,	CANV_INSERT,
	CANV_ITEMCGET,	CANV_ITEMCONFIGURE,
	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_RAISE,	CANV_RCHARS,	CANV_SCALE,	CANV_SCAN,
	CANV_SELECT,	CANV_TYPE,	CANV_XVIEW,	CANV_YVIEW
	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) {
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(canvasPtr);

    result = TCL_OK;
    switch ((enum canvasOptionStringsEnum)idx) {
    switch ((enum options)index) {
    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);
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
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







-
-
-
-
+
+
+
+



















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		    }
		}
	    }
	}
	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);
	    resultObjs[0] = Tcl_NewIntObj(x1);
	    resultObjs[1] = Tcl_NewIntObj(y1);
	    resultObjs[2] = Tcl_NewIntObj(x2);
	    resultObjs[3] = Tcl_NewIntObj(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;
#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 = Tcl_GetHashValue(entryPtr);
		object = itemPtr;
	    }

	    if (object == NULL) {
		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 {
	bindByTag:
	    object = 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;

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
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







-
+

+



















+





-
+







			"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;
	    object = (void *)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 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;
	    }
#ifndef USE_OLD_TAG_SEARCH
	    if (searchPtr->type == SEARCH_TYPE_EXPR) {
		/*
		 * If new tag expression, then insert in linked list.
		 */

	    	TagSearchExpr *expr, **lastPtr;
		TagSearchExpr *expr, **lastPtr;

		lastPtr = &(canvasPtr->bindTagExprs);
		while ((expr = *lastPtr) != NULL) {
		    if (expr->uid == searchPtr->expr->uid) {
			break;
		    }
		    lastPtr = &(expr->next);
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026







+







		     * 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) {
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1181
1182
1183
1184
1185
1186
1187

1188
1189
1190
1191
1192
1193
1194







-







	 * 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.
1246
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260


1261
1262
1263
1264
1265
1266
1267
1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249

1250
1251
1252
1253
1254
1255
1256
1257
1258







-
+






-
+
+







    }
    case CANV_CREATE: {
	Tk_ItemType *typePtr;
	Tk_ItemType *matchPtr = NULL;
	int isNew = 0;
	Tcl_HashEntry *entryPtr;
	const char *arg;
	TkSizeT length;
	size_t length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	arg = Tcl_GetString(objv[2]);
	length = 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.
	 */
1331
1332
1333
1334
1335
1336
1337
1338

1339
1340
1341
1342

1343
1344
1345
1346
1347
1348
1349
1322
1323
1324
1325
1326
1327
1328

1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
1340







-
+



-
+







	} 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));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id));
	break;
    }
    case CANV_DCHARS: {
	TkSizeT first, last;
	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;
	}
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
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







-
+


-
-
-
+
+
+

-
-
-
+
+
+


-
-
-
-
+
+
+
+

-
+







	}
	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--) {
	    for (i = itemPtr->numTags-1; i >= 0; i--) {
		if (itemPtr->tagPtr[i] == tag) {

                    /*
                     * Don't shuffle the tags sequence: memmove the tags.
                     */
		    /*
		     * 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));
		    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.
                     */
		    /*
		     * 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 ...?");
1490
1491
1492
1493
1494
1495
1496
1497

1498
1499
1500
1501
1502
1503
1504
1481
1482
1483
1484
1485
1486
1487

1488
1489
1490
1491
1492
1493
1494
1495







-
+







	    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));
		Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id));
	    }
	    goto done;
	}
	if (canvasPtr->textInfo.gotFocus) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	}
	if (Tcl_GetString(objv[2])[0] == 0) {
1525
1526
1527
1528
1529
1530
1531
1532

1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1516
1517
1518
1519
1520
1521
1522

1523
1524
1525
1526
1527
1528
1529
1530

1531
1532
1533
1534
1535
1536
1537







-
+







-







	    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++) {
	    for (i = 0; i < 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) {
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1548
1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559
1560
1561







-







		    && (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) {
1582
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593

1594
1595
1596
1597
1598
1599
1600
1571
1572
1573
1574
1575
1576
1577

1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
1589







-
+



-
+







	    result = TCL_ERROR;
	    goto done;
	}
	result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);
	if (result != TCL_OK) {
	    goto done;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	break;
    }
    case CANV_INSERT: {
	TkSizeT beforeThis;
	int beforeThis;
	int x1, x2, y1, y2;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
	    result = TCL_ERROR;
	    goto done;
	}
1674
1675
1676
1677
1678
1679
1680





1681
1682
1683
1684
1685
1686
1687
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681







+
+
+
+
+







	 */

	if (objc == 3) {
	    itemPtr = NULL;
	} else {
	    FIRST_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done);
	    if (itemPtr == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"tagOrId \"%s\" doesn't match any items",
			Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    itemPtr = itemPtr->prevPtr;
	}
	RELINK_ITEMS(objv[2], itemPtr);
	break;
    }
1796
1797
1798
1799
1800
1801
1802





1803
1804
1805
1806
1807
1808
1809
1810

1811
1812
1813
1814
1815
1816
1817
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







+
+
+
+
+







-
+







	    prevPtr = canvasPtr->lastItemPtr;
	} else {
	    prevPtr = NULL;
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
		prevPtr = itemPtr;
	    }
	    if (prevPtr == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"tagOrId \"%s\" doesn't match any items",
			Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	}
	RELINK_ITEMS(objv[2], prevPtr);
	break;
    }
    case CANV_RCHARS: {
	TkSizeT first, last;
	int 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;
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
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







-
+



-
+



-
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	     * 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;
	    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;
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemInsert(canvasPtr, itemPtr, first, objv[5]);
	    dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

            if (!(dontRedraw1 && dontRedraw2)) {
	    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,
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
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







-
+

-
-
+
+







-
+







	    "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) {
		"scan option", 0, &index) != TCL_OK) {
	    result = TCL_ERROR;
	} else if ((objc != 5) && (objc != 5+idx)) {
	    Tcl_WrongNumArgs(interp, 3, objv, idx?"x y ?gain?":"x y");
	} 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 (!idx) {
	} 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
1931
1932
1933
1934
1935
1936
1937

1938
1939
1940
1941
1942
1943
1944







-







		    - 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
	};
2006
2007
2008
2009
2010
2011
2012
2013
2014


2015
2016
2017
2018
2019
2020
2021
1980
1981
1982
1983
1984
1985
1986


1987
1988
1989
1990
1991
1992
1993
1994
1995







-
-
+
+







	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)) {
		if (index < (canvasPtr->textInfo.selectFirst
			+ canvasPtr->textInfo.selectLast)/2) {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectLast + 1;
		} else {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectFirst;
		}
	    }
2043
2044
2045
2046
2047
2048
2049
2050

2051
2052
2053
2054
2055
2056
2057
2017
2018
2019
2020
2021
2022
2023

2024
2025
2026
2027
2028
2029
2030
2031







-
+







	    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));
			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;
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
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







-










-
-
+
-
-
-

-
-
-

















+
+
+









-










-
-
+
-
-
-

-
-
-
















-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
+
-
-
-
-
+
-
-
-
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

+

+







	}
	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);
	type = Tk_GetScrollInfoObj(interp, objc, objv, &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;
	default:
	    result = TCL_ERROR;
	    goto done;
	}
	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);
	type = Tk_GetScrollInfoObj(interp, objc, objv, &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;

	default:
        if (objc < 3 || objc > 5) {
            Tcl_WrongNumArgs(interp, 2, objv, "imagename ?subsample? ?zoom?");
            result = TCL_ERROR;
            goto done;
        }

	    result = TCL_ERROR;
	    goto done;
	}
	CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
        if ((photohandle = Tk_FindPhoto(interp, Tcl_GetString(objv[2]) )) == 0) {
            result = TCL_ERROR;
            goto done;
        }

	break;
        /*
         * 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:
#ifndef USE_OLD_TAG_SEARCH
    TagSearchDestroy(searchPtr);
#endif /* not USE_OLD_TAG_SEARCH */
    Tcl_Release(canvasPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
2228
2229
2230
2231
2232
2233
2234
2235

2236
2237
2238

2239

2240
2241
2242
2243
2244
2245
2246
2154
2155
2156
2157
2158
2159
2160

2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174







-
+



+

+







 *	Everything associated with the canvas is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyCanvas(
    void *memPtr)		/* Info about canvas widget. */
    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) {
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
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







+






+




-
+







     * 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);
    Tk_FreeOptions(configSpecs, (char *)canvasPtr, canvasPtr->display, 0);
    canvasPtr->tkwin = NULL;
    ckfree(canvasPtr);
}

/*
 *----------------------------------------------------------------------
 *
2342
2343
2344
2345
2346
2347
2348
2349

2350
2351
2352
2353
2354
2355
2356
2272
2273
2274
2275
2276
2277
2278

2279
2280
2281
2282
2283
2284
2285
2286







-
+







     */

    if ( old_canvas_state != canvasPtr->canvas_state ) {
	Tk_Item *itemPtr;
	int result;

	for ( itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    	    	    itemPtr = itemPtr->nextPtr) {
		itemPtr = itemPtr->nextPtr) {
	    if ( itemPtr->state == TK_STATE_NULL ) {
		result = (*itemPtr->typePtr->configProc)(canvasPtr->interp,
			(Tk_Canvas) canvasPtr, itemPtr, 0, NULL,
			TK_CONFIG_ARGV_ONLY);
		if (result != TCL_OK) {
		    Tcl_ResetResult(canvasPtr->interp);
		}
2389
2390
2391
2392
2393
2394
2395
2396

2397
2398
2399
2400
2401
2402
2403
2319
2320
2321
2322
2323
2324
2325

2326
2327
2328
2329
2330
2331
2332
2333







-
+







	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);
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SCROLL_REGION", (char *)NULL);
	badRegion:
	    ckfree(canvasPtr->regionString);
	    ckfree(argv2);
	    canvasPtr->regionString = NULL;
	    return TCL_ERROR;
	}
	if ((Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
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
2412
2413
2414
2415
2416
2417
2418














































































































































































































































































































































































































































































































2419
2420
2421
2422
2423
2424
2425







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	    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:
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
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







+
+
+
+














-
-
+
+







    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;
#ifdef MAC_OSX_TK
    TkWindow *winPtr;
    MacDrawable *macWin;
#endif

    if (canvasPtr->tkwin == NULL) {
	return;
    }

    if (!Tk_IsMapped(tkwin)) {
	goto done;
    }

#ifdef MAC_OSX_TK
    /*
     * If drawing is disabled, all we need to do is
     * clear the REDRAW_PENDING flag.
     */
    TkWindow *winPtr = (TkWindow *)(canvasPtr->tkwin);
    MacDrawable *macWin = winPtr->privatePtr;
    winPtr = (TkWindow *)(canvasPtr->tkwin);
    macWin = winPtr->privatePtr;
    if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
	canvasPtr->flags &= ~REDRAW_PENDING;
	return;
    }
#endif

    /*
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
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







-
+







-
+


-
+







	    Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin),
		    canvasPtr->bgBorder, canvasPtr->highlightWidth,
		    canvasPtr->highlightWidth,
		    Tk_Width(tkwin) - 2*canvasPtr->highlightWidth,
		    Tk_Height(tkwin) - 2*canvasPtr->highlightWidth,
		    canvasPtr->borderWidth, canvasPtr->relief);
	}
	if (canvasPtr->highlightWidth != 0) {
	if (canvasPtr->highlightWidth > 0) {
	    GC fgGC, bgGC;

	    bgGC = Tk_GCForColor(canvasPtr->highlightBgColorPtr,
		    Tk_WindowId(tkwin));
	    if (canvasPtr->textInfo.gotFocus) {
		fgGC = Tk_GCForColor(canvasPtr->highlightColorPtr,
			Tk_WindowId(tkwin));
	    	TkpDrawHighlightBorder(tkwin, fgGC, bgGC,
		TkpDrawHighlightBorder(tkwin, fgGC, bgGC,
			canvasPtr->highlightWidth, Tk_WindowId(tkwin));
	    } else {
	    	TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
		TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
			canvasPtr->highlightWidth, Tk_WindowId(tkwin));
	    }
	}
    }

  done:
    canvasPtr->flags &= ~(REDRAW_PENDING|BBOX_NOT_EMPTY);
3276
3277
3278
3279
3280
3281
3282
3283

3284
3285
3286
3287
3288
3289
3290
2716
2717
2718
2719
2720
2721
2722

2723
2724
2725
2726
2727
2728
2729
2730







-
+







	    canvasPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(canvasPtr->interp,
		    canvasPtr->widgetCmd);
	}
	if (canvasPtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayCanvas, canvasPtr);
	}
	Tcl_EventuallyFree(canvasPtr, (Tcl_FreeProc *) DestroyCanvas);
	Tcl_EventuallyFree(canvasPtr, 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.
	 */
3392
3393
3394
3395
3396
3397
3398
3399

3400
3401
3402
3403
3404
3405
3406
2832
2833
2834
2835
2836
2837
2838

2839
2840
2841
2842
2843
2844
2845
2846







-
+







     */

    if (canvasPtr->tkwin == NULL) {
	return;
    }

    if ((x1 >= x2) || (y1 >= y2) ||
 	    (x2 < canvasPtr->xOrigin) || (y2 < canvasPtr->yOrigin) ||
	    (x2 < canvasPtr->xOrigin) || (y2 < canvasPtr->yOrigin) ||
	    (x1 >= canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)) ||
	    (y1 >= canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin))) {
	return;
    }
    if (canvasPtr->flags & BBOX_NOT_EMPTY) {
	if (x1 <= canvasPtr->redrawX1) {
	    canvasPtr->redrawX1 = x1;
3450
3451
3452
3453
3454
3455
3456
3457

3458
3459
3460
3461
3462
3463
3464
2890
2891
2892
2893
2894
2895
2896

2897
2898
2899
2900
2901
2902
2903
2904







-
+







    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->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;
	}
    }
3607
3608
3609
3610
3611
3612
3613










































































































































































































3614
3615
3616
3617
3618
3619
3620
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    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 = (TkWindow *) canvasPtr->tkwin;
    TkDisplay *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 = 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
3698
3699
3700
3701
3702
3703
3704
3705

3706
3707
3708
3709
3710
3711
3712
3340
3341
3342
3343
3344
3345
3346

3347
3348
3349
3350
3351
3352
3353
3354







-
+







 */

static void
TagSearchExprDestroy(
    TagSearchExpr *expr)
{
    if (expr != NULL) {
    	if (expr->uids) {
	if (expr->uids) {
	    ckfree(expr->uids);
	}
	ckfree(expr);
    }
}

/*
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
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







-
+



















-
+







		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;
		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 = (int)itemPtr->numTags;
		for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
			count > 0; tagPtr++, count--) {
		    if (*tagPtr == uid) {
			result = 1;
			break;
		    }
		}

4403
4404
4405
4406
4407
4408
4409
4410

4411
4412
4413
4414
4415
4416
4417
4045
4046
4047
4048
4049
4050
4051

4052
4053
4054
4055
4056
4057
4058
4059







-
+







	/*
	 * 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;
	    for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
		    count > 0; tagPtr++, count--) {
		if (*tagPtr == uid) {
		    searchPtr->lastPtr = lastPtr;
		    searchPtr->currentPtr = itemPtr;
		    return itemPtr;
		}
	    }
4505
4506
4507
4508
4509
4510
4511
4512

4513
4514
4515
4516
4517
4518
4519
4147
4148
4149
4150
4151
4152
4153

4154
4155
4156
4157
4158
4159
4160
4161







-
+







    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;
	    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
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191







+







	    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
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
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







-
+



-
+















-
+







    int count;

    /*
     * Handle the "add-to-result" case and return, if appropriate.
     */

    if (tag == NULL) {
	Tcl_ListObjAppendElement(NULL, accumObj, Tcl_NewWideIntObj(itemPtr->id));
	Tcl_ListObjAppendElement(NULL, accumObj, Tcl_NewIntObj(itemPtr->id));
	return;
    }

    for (tagPtr = itemPtr->tagPtr, count = (int)itemPtr->numTags;
    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(itemPtr->tagSpace * sizeof(Tk_Uid));
	memcpy((void *) newTagPtr, itemPtr->tagPtr,
	memcpy(newTagPtr, itemPtr->tagPtr,
		itemPtr->numTags * sizeof(Tk_Uid));
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newTagPtr;
	tagPtr = &itemPtr->tagPtr[itemPtr->numTags];
    }
4647
4648
4649
4650
4651
4652
4653

4654

4655
4656



4657
4658
4659
4660
4661
4662
4663
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311







+

+


+
+
+







    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;
    Tcl_Obj *resultObj;
    static const char *const optionStrings[] = {
	"above", "all", "below", "closest",
	"enclosed", "overlapping", "withtag", NULL
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
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







+
+
+
+
+
+
+
+
+
+









+


+
+
+







 *	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.
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
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







+
+
+

+




















+

+








    /*
     * 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 --
 *
5089
5090
5091
5092
5093
5094
5095
5096

5097
5098
5099
5100
5101
5102
5103
4757
4758
4759
4760
4761
4762
4763

4764
4765
4766
4767
4768
4769
4770
4771







-
+







     * 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);
	mask = TkGetButtonMask(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).
5174
5175
5176
5177
5178
5179
5180

5181

5182
5183
5184
5185
5186
5187
5188
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858







+

+







    XEvent *eventPtr)		/* Event describing location of mouse cursor.
				 * Must be EnterWindow, LeaveWindow,
				 * ButtonRelease, or MotionNotify. */
{
    double coords[2];
    unsigned 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.
     */
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
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







+
-
-
-
+
+
+
+
+
+
+
+
+
+













-
+
+
+
+

+

-
-
-
+
+
+







	Tk_Item *itemPtr = canvasPtr->currentItemPtr;
	int i;

	event = canvasPtr->pickEvent;
	event.type = LeaveNotify;

	/*
	 * Behaviour before ticket #47d4f29159:
	 * If the event's detail happens to be NotifyInferior the binding
	 * mechanism will discard the event. To be consistent, always use
	 * NotifyAncestor.
	 *    If the event's detail happens to be NotifyInferior the binding
	 *    mechanism will discard the event. To be consistent, always use
	 *    NotifyAncestor.
	 *
	 * Behaviour after ticket #47d4f29159:
	 *    The binding mechanism doesn't discard events with detail field
	 *    NotifyInferior anymore. It would be best to base the detail
	 *    field on the ancestry relationship between the old and new
	 *    canvas items. For the time being, retain the choice from before
	 *    ticket #47d4f29159, which doesn't harm.
	 */

	event.xcrossing.detail = NotifyAncestor;
	canvasPtr->flags |= REPICK_IN_PROGRESS;
	CanvasDoEvent(canvasPtr, &event);
	canvasPtr->flags &= ~REPICK_IN_PROGRESS;

	/*
	 * 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--) {
	    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 */ {
                    memmove((void *)(itemPtr->tagPtr + i),
                            itemPtr->tagPtr + i + 1,
                            (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    memmove((void *)(itemPtr->tagPtr + i),
			    itemPtr->tagPtr + i + 1,
			    (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;
		    break;
		}
	    }
	}

	/*
5335
5336
5337
5338
5339
5340
5341



5342

5343
5344
5345
5346
5347
5348
5349
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035







+
+
+

+







	    (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) {
	EventuallyRedrawItem(canvasPtr, prevItemPtr);
	ItemConfigure(canvasPtr, prevItemPtr, 0, NULL);
    }
    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_SEARCH */
	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;
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
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







+



+













+
+
+
+
+
+
+
+
+
+




















-
+







+





+
+
+
-
-
-
+
+
+
+



+







-
+




+







				 * processed. */
{
#define NUM_STATIC 3
    void *staticObjects[NUM_STATIC];
    void **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".
     *
     * If there are a lot of tags then malloc an array to hold all of the
     * objects.
     */

    /*
     * Flag and count all expressions that match item's tags.
     */

    numExprs = 0;
    expr = canvasPtr->bindTagExprs;
    while (expr) {
	expr->index = 0;
    	expr->match = TagSearchEvalExpr(expr, itemPtr);
	expr->match = TagSearchEvalExpr(expr, itemPtr);
	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 = (void **)ckalloc(numObjects * sizeof(void *));
    }
#ifdef USE_OLD_TAG_SEARCH
    objectPtr[0] = (void *)Tk_GetUid("all");
#else /* USE_OLD_TAG_SEARCH */
    objectPtr[0] = (char *)searchUids->allUid;
    for (i = (int)itemPtr->numTags - 1; i >= 0; i--) {
	objectPtr[i+1] = (char *)itemPtr->tagPtr[i];
    objectPtr[0] = (void *)searchUids->allUid;
#endif /* USE_OLD_TAG_SEARCH */
    for (i = itemPtr->numTags - 1; i >= 0; i--) {
	objectPtr[i+1] = (void *)itemPtr->tagPtr[i];
    }
    objectPtr[itemPtr->numTags + 1] = 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) {
	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) {
5622
5623
5624
5625
5626
5627
5628
5629

5630
5631
5632

5633
5634
5635
5636
5637
5638
5639
5327
5328
5329
5330
5331
5332
5333

5334
5335
5336

5337
5338
5339
5340
5341
5342
5343
5344







-
+


-
+







 *----------------------------------------------------------------------
 */

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
    int index)			/* Index of element that is to become the
				 * "other" end of the selection. */
{
    TkSizeT oldFirst, oldLast;
    int oldFirst, oldLast;
    Tk_Item *oldSelPtr;

    oldFirst = canvasPtr->textInfo.selectFirst;
    oldLast = canvasPtr->textInfo.selectLast;
    oldSelPtr = canvasPtr->textInfo.selItemPtr;

    /*
5648
5649
5650
5651
5652
5653
5654
5655

5656
5657
5658
5659

5660
5661
5662
5663
5664
5665
5666
5353
5354
5355
5356
5357
5358
5359

5360
5361
5362
5363

5364
5365
5366
5367
5368
5369
5370
5371







-
+



-
+







    }
    canvasPtr->textInfo.selItemPtr = itemPtr;

    if (canvasPtr->textInfo.anchorItemPtr != itemPtr) {
	canvasPtr->textInfo.anchorItemPtr = itemPtr;
	canvasPtr->textInfo.selectAnchor = index;
    }
    if (canvasPtr->textInfo.selectAnchor + 1 <= index + 1) {
    if (canvasPtr->textInfo.selectAnchor <= index) {
	canvasPtr->textInfo.selectFirst = canvasPtr->textInfo.selectAnchor;
	canvasPtr->textInfo.selectLast = index;
    } else {
	canvasPtr->textInfo.selectFirst = ((int)index < 0) ? TCL_INDEX_NONE : index;
	canvasPtr->textInfo.selectFirst = index;
	canvasPtr->textInfo.selectLast = canvasPtr->textInfo.selectAnchor - 1;
    }
    if ((canvasPtr->textInfo.selectFirst != oldFirst)
	    || (canvasPtr->textInfo.selectLast != oldLast)
	    || (itemPtr != oldSelPtr)) {
	EventuallyRedrawItem(canvasPtr, itemPtr);
    }
5683
5684
5685
5686
5687
5688
5689
5690

5691
5692
5693

5694
5695
5696

5697
5698
5699
5700
5701
5702
5703
5388
5389
5390
5391
5392
5393
5394

5395
5396
5397

5398
5399
5400

5401
5402
5403
5404
5405
5406
5407
5408







-
+


-
+


-
+







 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
static int
CanvasFetchSelection(
    ClientData clientData,	/* Information about canvas widget. */
    TkSizeT offset,			/* Offset within selection of first character
    int 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,
    int 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);
Changes to generic/tkCanvas.h.
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15







-
+







/*
 * tkCanvas.h --
 *
 *	Declarations shared among all the files that implement canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 * Copyright (c) 1998 by Scriptics Corporation.
 * Copyright (c) 1998 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKCANVAS
#define _TKCANVAS
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
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
    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
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
    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. */

    /*
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251







-
+







} TkCanvas;

/*
 * Flag bits for canvases:
 *
 * REDRAW_PENDING -		1 means a DoWhenIdle handler has already been
 *				created to redraw some or all of the canvas.
 * REDRAW_BORDERS - 		1 means that the borders need to be redrawn
 * REDRAW_BORDERS -		1 means that the borders need to be redrawn
 *				during the next redisplay operation.
 * REPICK_NEEDED -		1 means DisplayCanvas should pick a new
 *				current item before redrawing the canvas.
 * GOT_FOCUS -			1 means the focus is currently in this widget,
 *				so should draw the insertion cursor and
 *				traversal highlight.
 * CURSOR_ON -			1 means the insertion cursor is in the "on"
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302







-
+







/*
 * 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,
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;
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
15
16
17
18
19
20
21






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







-
-
-
-
-
-
+
+
+
+
+
+







#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 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, const char *portion);

/*
 *----------------------------------------------------------------------
 *
44
45
46
47
48
49
50
51

52
53
54

55
56
57

58
59
60
61
62
63
64



65
66
67
68
69
70
71
44
45
46
47
48
49
50

51
52
53

54
55
56

57
58
59
60
61



62
63
64
65
66
67
68
69
70
71







-
+


-
+


-
+




-
-
-
+
+
+







 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
ClipboardHandler(
    ClientData clientData,	/* Information about data to fetch. */
    TkSizeT offset,			/* Return selection bytes starting at this
    int offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
    int 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;
    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
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;
    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
122
123
124
125
126
127
128

129
130
131

132
133
134

135
136
137

138
139
140
141
142
143
144
145







-
+


-
+


-
+


-
+







 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
ClipboardAppHandler(
    ClientData clientData,	/* Pointer to TkDisplay structure. */
    TkSizeT offset,			/* Return selection bytes starting at this
    int offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
    int maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    TkSizeT length;
    int length;
    const char *p;

    p = dispPtr->clipboardAppPtr->winPtr->nameUid;
    length = strlen(p);
    if (length <= offset) {
	return 0;
    }
167
168
169
170
171
172
173
174

175
176
177

178
179
180

181
182
183
184
185
186
187
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
static int
ClipboardWindowHandler(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(TkSizeT),			/* Return selection bytes starting at this
    TCL_UNUSED(int),			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TCL_UNUSED(TkSizeT))		/* Maximum # of bytes to store at buffer. */
    TCL_UNUSED(int))		/* Maximum # of bytes to store at buffer. */
{
    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*
446
447
448
449
450
451
452
453

454
455
456
457

458
459
460
461
462
463
464
446
447
448
449
450
451
452

453

454
455

456
457
458
459
460
461
462
463







-
+
-


-
+







	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;
	int subIndex, length;
	TkSizeT length;

	for (i = 2; i < objc - 1; i++) {
	    string = TkGetStringFromObj(objv[i], &length);
	    string = Tcl_GetStringFromObj(objv[i], &length);
	    if (string[0] != '-') {
		break;
	    }

	    /*
	     * If the argument is "--", it signifies the end of arguments.
	     */
705
706
707
708
709
710
711




712



713
714
715
716
717
718
719
720
721
722
704
705
706
707
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722
723
724
725
726
727







+
+
+
+
-
+
+
+










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_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
    Tcl_DString ds;

    Tcl_ExternalToUtfDString(utf8, portion, -1, &ds);
    Tcl_DStringAppend((Tcl_DString *)clientData, portion, -1);
    Tcl_DStringAppend((Tcl_DString *) clientData, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);
    Tcl_FreeEncoding(utf8);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkCmds.c.
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
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







-
+



-
+



-
+



















-
+

+
-
+







	 * 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_NewIntObj(caretPtr->height));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-x", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->x));
		Tcl_NewIntObj(caretPtr->x));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-y", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->y));
		Tcl_NewIntObj(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));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(value));
    } else {
	int i;
	int i, value, x = 0, y = 0, height = -1;
	int 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;
	    }
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
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 *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 (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"setting the scaling not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "SCALING", NULL);
	return TCL_ERROR;
    } 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) {
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
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







+
+
+
+
+







+
-
+




+








    skip = TkGetDisplayOf(interp, objc-1, objv+1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if ((objc - skip) == 2) {
	/*
	 * 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[1+skip],
		&boolVal) != TCL_OK) {
	    return TCL_ERROR;
	}
#ifdef TK_USE_INPUT_METHODS
	if (boolVal && (dispPtr->inputMethod != NULL)) {
	if (boolVal) {
	    dispPtr->flags |= TK_DISPLAY_USE_IM;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_USE_IM;
	}
#endif /* TK_USE_INPUT_METHODS */
    } 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));
1109
1110
1111
1112
1113
1114
1115
1116
1117


1118
1119
1120
1121
1122
1123


1124
1125
1126
1127
1128
1129
1130
1115
1116
1117
1118
1119
1120
1121


1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138







-
-
+
+






+
+








    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_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* 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;
    Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    WaitVariableProc, clientData);
    return NULL;
}

static void
WaitVisibilityProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event (not used). */
1346
1347
1348
1349
1350
1351
1352
1353

1354
1355
1356
1357
1358
1359
1360
1354
1355
1356
1357
1358
1359
1360

1361
1362
1363
1364
1365
1366
1367
1368







-
+







	}
    }
    winPtr = (TkWindow *) tkwin;

    switch ((enum options) index) {
    case WIN_CELLS:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(Tk_Visual(tkwin)->map_entries));
		Tcl_NewIntObj(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)) {
1369
1370
1371
1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390

1391
1392
1393
1394
1395
1396
1397
1398







-
+






-
+







	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)));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(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)));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(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));
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
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







-
-
+
+


-
+

-
+



-
+


-
+



-
+



-
+







-
+



-
+



-
+



-
+



-
+



-
+







	    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);
	    xyObj[0] = Tcl_NewIntObj(x);
	    xyObj[1] = Tcl_NewIntObj(y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, xyObj));
	} else if (useX) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(y));
	}
	break;
    case WIN_REQHEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_ReqHeight(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_ReqHeight(tkwin)));
	break;
    case WIN_REQWIDTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_ReqWidth(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_ReqWidth(tkwin)));
	break;
    case WIN_ROOTX:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
	break;
    case WIN_ROOTY:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(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))));
		Tcl_NewIntObj(CellsOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENDEPTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(DefaultDepthOfScreen(Tk_Screen(tkwin))));
		Tcl_NewIntObj(DefaultDepthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(HeightOfScreen(Tk_Screen(tkwin))));
		Tcl_NewIntObj(HeightOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(WidthOfScreen(Tk_Screen(tkwin))));
		Tcl_NewIntObj(WidthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(HeightMMOfScreen(Tk_Screen(tkwin))));
		Tcl_NewIntObj(HeightMMOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(WidthMMOfScreen(Tk_Screen(tkwin))));
		Tcl_NewIntObj(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;
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
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







-
+



-
+



-
+



-
+


-
+


-
+


-
+







	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));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(height));
	break;
    case WIN_VROOTWIDTH:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(width));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(width));
	break;
    case WIN_VROOTX:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
	break;
    case WIN_VROOTY:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(y));
	break;
    case WIN_WIDTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Width(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Width(tkwin)));
	break;
    case WIN_X:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_X(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_X(tkwin)));
	break;
    case WIN_Y:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Y(tkwin)));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Y(tkwin)));
	break;

	/*
	 * Uses -displayof.
	 */

    case WIN_ATOM:
1718
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1726
1727
1728
1729
1730
1731
1732

1733
1734
1735
1736
1737
1738
1739
1740







-
+







	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));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(pixels));
	break;
    }
    case WIN_RGB: {
	XColor *colorPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
1742
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753

1754
1755
1756
1757
1758
1759
1760
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760

1761
1762
1763
1764
1765
1766
1767
1768







-
+



-
+







	 * 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]));
	    colorPtr = Tk_AllocColorFromObj(interp, tkwin, objv[3]);
	    Tk_Colormap(tkwin) = temp;
	}
#else
	colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
	colorPtr = Tk_AllocColorFromObj(interp, tkwin, 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);
1793
1794
1795
1796
1797
1798
1799
1800

1801
1802
1803

1804
1805
1806
1807
1808
1809
1810
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810

1811
1812
1813
1814
1815
1816
1817
1818







-
+


-
+







	}
	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);
		snprintf(buf, sizeof(buf), "%s %d", string, visInfoPtr[i].depth);
	    }
	    if (includeVisualId) {
		sprintf(visualIdString, " 0x%lx",
		snprintf(visualIdString, sizeof(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);
1853
1854
1855
1856
1857
1858
1859
1860

1861
1862
1863
1864
1865

1866
1867
1868
1869
1870
1871
1872
1861
1862
1863
1864
1865
1866
1867

1868
1869
1870
1871
1872

1873
1874
1875
1876
1877
1878
1879
1880







-
+




-
+







				 * 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;
    int length;

    if (objc < 1) {
	return 0;
    }
    string = TkGetStringFromObj(objv[0], &length);
    string = Tcl_GetStringFromObj(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;
Changes to generic/tkColor.c.
11
12
13
14
15
16
17




18
19
20
21
22
23
24
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.
 */

#include "tkInt.h"
#include "tkColor.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Structures of the following following type are used as keys for
 * colorValueTable (in TkDisplay).
 */

typedef struct {
    int red, green, blue;	/* Values for desired color. */
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385







-
+








    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,
	snprintf(tsdPtr->rgbString, sizeof(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.
	 */
814
815
816
817
818
819
820
821

822
823

824
825
826
827
828
829
830
818
819
820
821
822
823
824

825
826

827
828
829
830
831
832
833
834







-
+

-
+







	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_NewIntObj(tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(tkColPtr->objRefCount));
		    Tcl_NewIntObj(tkColPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef _WIN32
Changes to generic/tkColor.h.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * tkColor.h --
 *
 *	Declarations of data types and functions used by the Tk color module.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKCOLOR
#define _TKCOLOR
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
34
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
    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. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
    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
Changes to generic/tkConfig.c.
22
23
24
25
26
27
28














29
30
31
32
33
34
35
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49







+
+
+
+
+
+
+
+
+
+
+
+
+
+








#define __NO_OLD_CONFIG
#endif

#include "tkInt.h"
#include "tkFont.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following encoding is used in TYPE_FLAGS:
 *
 * if sizeof(type) == sizeof(int)     =>    TYPE_FLAGS(type) = 0
 * if sizeof(type) == 1               =>    TYPE_FLAGS(type) = 64
 * if sizeof(type) == 2               =>    TYPE_FLAGS(type) = 128
 */
#define TYPE_FLAGS(type) (((int)(sizeof(type)&(sizeof(int)-1))<<6))
#define TYPE_MASK        (((((int)sizeof(int)-1))|3)<<6)

/*
 * 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. */
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123


124
125

126
127
128
129
130
131
132
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135


136
137
138

139
140
141
142
143
144
145
146







-
+











-
+











-
+



-
-
+
+

-
+








/*
 * 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
    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. */
    size_t numOptions;		/* The number of items in the options array
    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, void *recordPtr,
static int		DoObjConfig(Tcl_Interp *interp, char *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,
			    char *internalPtr, Tk_Window tkwin);
static Tcl_Obj *	GetConfigList(char *recordPtr,
			    Option *optionPtr, Tk_Window tkwin);
static Tcl_Obj *	GetObjectForOption(void *recordPtr,
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 void		FreeOptionInternalRep(Tcl_Obj *objPtr);
static void		DupOptionInternalRep(Tcl_Obj *, Tcl_Obj *);
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201







-
+







				 * options. */
{
    Tcl_HashEntry *hashEntryPtr;
    int newEntry;
    OptionTable *tablePtr;
    const Tk_OptionSpec *specPtr, *specPtr2;
    Option *optionPtr;
    size_t numOptions, i;
    int 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).
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303







-
+







		 * 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->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;
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+








void
Tk_DeleteOptionTable(
    Tk_OptionTable optionTable)	/* The option table to delete. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    size_t count;
    int count;

    if (tablePtr->refCount-- > 1) {
	return;
    }

    if (tablePtr->nextPtr != NULL) {
	Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr);
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405







-
+







 *--------------------------------------------------------------
 */

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:
    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
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
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







-
+



-
+



-
+



-
+







	if (DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin,
		NULL) != TCL_OK) {
	    if (interp != NULL) {
		char msg[200];

		switch (source) {
		case OPTION_DATABASE:
		    sprintf(msg, "\n    (database entry for \"%.50s\")",
		    snprintf(msg, 200, "\n    (database entry for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		    break;
		case SYSTEM_DEFAULT:
		    sprintf(msg, "\n    (system default for \"%.50s\")",
		    snprintf(msg, 200, "\n    (system default for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		    break;
		case TABLE_DEFAULT:
		    sprintf(msg, "\n    (default value for \"%.50s\")",
		    snprintf(msg, 200, "\n    (default value for \"%.50s\")",
			    optionPtr->specPtr->optionName);
		}
		if (tkwin != NULL) {
		    sprintf(msg + strlen(msg) - 1, " in widget \"%.50s\")",
		    snprintf(msg + strlen(msg) - 1, 200 - (strlen(msg) - 1), " in widget \"%.50s\")",
			    Tk_PathName(tkwin));
		}
		Tcl_AddErrorInfo(interp, msg);
	    }
	    Tcl_DecrRefCount(valuePtr);
	    return TCL_ERROR;
	}
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
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







-
+















-
+


-
+












-
-
+
+











-
-
+
+










-
+







 */

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
    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;
    void *internalPtr;		/* Points to location in record where internal
    char *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
    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 != TCL_INDEX_NONE) {
	slotPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
    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 != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + specPtr->internalOffset;
    if (specPtr->internalOffset >= 0) {
	internalPtr = recordPtr + specPtr->internalOffset;
    } else {
	internalPtr = NULL;
    }
    if (savedOptionPtr != NULL) {
	savedOptionPtr->optionPtr = optionPtr;
	savedOptionPtr->valuePtr = oldPtr;
	oldInternalPtr = (char *) &savedOptionPtr->internalForm;
    } else {
	oldInternalPtr = (char *) &internal.internalForm;
    }
    nullOK = (optionPtr->specPtr->flags & TK_OPTION_NULL_OK);
    nullOK = (optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|32 /* TCL_NULL_OK */));
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_BOOLEAN: {
	int newBool;

	if (Tcl_GetBooleanFromObj(interp, valuePtr, &newBool) != TCL_OK) {
	    return TCL_ERROR;
	}
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
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







-
+






-
+















-
-
+
+



-
+

-
+

+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+







	    *((double *) internalPtr) = newDbl;
	}
	break;
    }
    case TK_OPTION_STRING: {
	char *newStr;
	const char *value;
	TkSizeT length;
	int length;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	}
	if (internalPtr != NULL) {
	    if (valuePtr != NULL) {
		value = TkGetStringFromObj(valuePtr, &length);
		value = Tcl_GetStringFromObj(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 {
	    newValue = -1;
	} else {
	    if (Tcl_GetIndexFromObjStruct(interp, valuePtr,
		    optionPtr->specPtr->clientData, sizeof(char *),
		    optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) {
	        return TCL_ERROR;
		return TCL_ERROR;
	    }
        }
	}
	if (internalPtr != NULL) {
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) {
		    *((char *) oldInternalPtr) = *((char *) internalPtr);
		    *((char *) internalPtr) = newValue;
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) {
		    *((short *) oldInternalPtr) = *((short *) internalPtr);
		    *((short *) internalPtr) = newValue;
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		}
	    } else {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newValue;
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newValue;
	    }
	}
	break;
    }
    case TK_OPTION_COLOR: {
	XColor *newPtr;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
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
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







-
-
-
-
+
+
+
-













-
-
-
-
+
+
+
-











-
+







    }
    case TK_OPTION_PIXELS: {
	int newPixels;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newPixels = 0;
	} else {
	    if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr,
		    &newPixels) != TCL_OK) {
		return TCL_ERROR;
	} else if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr,
		&newPixels) != TCL_OK) {
	    return TCL_ERROR;
	    }
	}
	if (internalPtr != NULL) {
	    *((int *) oldInternalPtr) = *((int *) internalPtr);
	    *((int *) internalPtr) = newPixels;
	}
	break;
    }
    case TK_OPTION_WINDOW: {
	Tk_Window newWin;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newWin = NULL;
	} else {
	    if (TkGetWindowFromObj(interp, tkwin, valuePtr,
		    &newWin) != TCL_OK) {
		return TCL_ERROR;
	} else if (TkGetWindowFromObj(interp, tkwin, valuePtr,
		&newWin) != TCL_OK) {
	    return TCL_ERROR;
	    }
	}
	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,
		&valuePtr, recordPtr, optionPtr->specPtr->internalOffset,
		(char *)oldInternalPtr, optionPtr->specPtr->flags) != TCL_OK) {
	    return TCL_ERROR;
	}
	break;
    }

    default:
975
976
977
978
979
980
981
982

983
984
985
986
987
988
989
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011







-
+







    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;
    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
1223
1224
1225
1226
1227
1228
1229
1230

1231
1232
1233
1234
1235
1236
1237
1245
1246
1247
1248
1249
1250
1251

1252
1253
1254
1255
1256
1257
1258
1259







-
+







 *--------------------------------------------------------------
 */

int
Tk_SetOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is returned.*/
    void *recordPtr,	    	/* The record to configure. */
    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
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
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







-
+




-
+














-
+








-
-
+
+



-
-
+
+














-
-
+
+


-
+















+
+
+
+
+
+
+
+
+
-
+
+







 */

void
Tk_RestoreSavedOptions(
    Tk_SavedOptions *savePtr)	/* Holds saved option information; must have
				 * been passed to Tk_SetOptions. */
{
    size_t i;
    int 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
    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(savePtr->nextPtr);
	savePtr->nextPtr = NULL;
    }
    for (i = savePtr->numItems - 1; i != (size_t)-1; i--) {
    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 != TCL_INDEX_NONE) {
	    newPtr = *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset));
	if (specPtr->objOffset >= 0) {
	    newPtr = *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset));
	} else {
	    newPtr = NULL;
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    internalPtr = (char *)savePtr->recordPtr + specPtr->internalOffset;
	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 != TCL_INDEX_NONE) {
	    *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset))
	if (specPtr->objOffset >= 0) {
	    *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset))
		    = savePtr->items[i].valuePtr;
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	if (specPtr->internalOffset >= 0) {
	    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:
		*((char **) internalPtr) = *((char **) ptr);
		break;
	    case TK_OPTION_STRING_TABLE:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) {
			*((char *) internalPtr) = *((char *) ptr);
		    } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) {
			*((short *) internalPtr) = *((short *) ptr);
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		    }
		} else {
		*((int *) internalPtr) = *((int *) ptr);
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_COLOR:
		*((XColor **) internalPtr) = *((XColor **) ptr);
		break;
	    case TK_OPTION_FONT:
		*((Tk_Font *) internalPtr) = *((Tk_Font *) ptr);
		break;
1452
1453
1454
1455
1456
1457
1458
1459

1460
1461
1462
1463
1464
1465
1466
1484
1485
1486
1487
1488
1489
1490

1491
1492
1493
1494
1495
1496
1497
1498







-
+







		*((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);
			    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
1518
1519
1520
1521
1522
1523
1524

1525
1526
1527
1528
1529
1530
1531
1532







-
+







 */

void
Tk_FreeSavedOptions(
    Tk_SavedOptions *savePtr)	/* Contains options saved in a previous call
				 * to Tk_SetOptions. */
{
    size_t count;
    int count;
    Tk_SavedOption *savedOptionPtr;

    if (savePtr->nextPtr != NULL) {
	Tk_FreeSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
    }
    for (count = savePtr->numItems; count > 0; count--) {
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
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







-
+







-
+

-
+










-
-
+
+





-
-
+
+







 *	options in optionTable are freed.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeConfigOptions(
    void *recordPtr,		/* Record whose fields contain current values
    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;
    size_t count;
    int count;
    Tcl_Obj **oldPtrPtr, *oldPtr;
    void *oldInternalPtr;
    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 != TCL_INDEX_NONE) {
		oldPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
	    if (specPtr->objOffset >= 0) {
		oldPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset);
		oldPtr = *oldPtrPtr;
		*oldPtrPtr = NULL;
	    } else {
		oldPtr = NULL;
	    }
	    if (specPtr->internalOffset != TCL_INDEX_NONE) {
		oldInternalPtr = (char *)recordPtr + specPtr->internalOffset;
	    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
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







-
+


-
+










-
+







 */

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
    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 != -1. */
				 * 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 != TCL_INDEX_NONE;
    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;
	    }
1671
1672
1673
1674
1675
1676
1677
1678

1679
1680
1681
1682
1683
1684
1685
1703
1704
1705
1706
1707
1708
1709

1710
1711
1712
1713
1714
1715
1716
1717







-
+







	} 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);
	    custom->freeProc(custom->clientData, tkwin, internalPtr);
	}
	break;
    }
    default:
	break;
    }
}
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
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







-
+













-
+







 *--------------------------------------------------------------
 */

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
    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;
    size_t count;
    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
1810
1811
1812
1813
1814
1815
1816

1817
1818
1819
1820
1821
1822
1823
1824







-
+







 *	Memory is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
GetConfigList(
    void *recordPtr,		/* Pointer to record holding current values of
    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
1853
1854
1855
1856
1857
1858
1859


1860
1861
1862
1863
1864
1865
1866
1867
1868







-
-
+
+







	} 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
	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
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







-
+






-
-
+
+
-

-
-
-
+
+


+
+

-
+


-
+




-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetObjectForOption(
    void *recordPtr,		/* Pointer to record holding current values of
    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;
    void *internalPtr;		/* Points to internal value of option in
    Tcl_Obj *objPtr = NULL;
    char *internalPtr;		/* Points to internal value of option in record. */
				 * record. */

    objPtr = NULL;
    if (optionPtr->specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
    if (optionPtr->specPtr->internalOffset >= 0) {
	internalPtr = recordPtr + optionPtr->specPtr->internalOffset;
	switch (optionPtr->specPtr->type) {
	case TK_OPTION_BOOLEAN:
	    objPtr = Tcl_NewIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_INT:
	    objPtr = Tcl_NewWideIntObj(*((int *)internalPtr));
	    objPtr = Tcl_NewIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_DOUBLE:
	    objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));
	    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);
	case TK_OPTION_STRING_TABLE: {
	    int value = 0;
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) {
		    value = *((signed char *)internalPtr);
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) {
		    value = *((short *)internalPtr);
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		}
	    } else {
		value = *((int *)internalPtr);
	    }
	    if (value >= 0) {
		objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
			value], -1);
	    }
	    break;
	}
	case TK_OPTION_COLOR: {
	    XColor *colorPtr = *((XColor **)internalPtr);

	    if (colorPtr != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
	    }
	    break;
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
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







-
+



















-
+












-
+


-
+









-
+


-
-
+
+







	    break;
	}
	case TK_OPTION_BITMAP: {
	    Pixmap pixmap = *((Pixmap *)internalPtr);

	    if (pixmap != None) {
		objPtr = Tcl_NewStringObj(
		    Tk_NameOfBitmap(Tk_Display(tkwin), pixmap), -1);
			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);
			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));
	    objPtr = Tcl_NewIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_WINDOW: {
	    tkwin = *((Tk_Window *) internalPtr);
	    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,
	    objPtr = custom->getProc(custom->clientData, tkwin, recordPtr,
		    optionPtr->specPtr->internalOffset);
	    break;
        }
        default:
	}
	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
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







-
+

















-
-
+
+







 */

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
    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 != TCL_INDEX_NONE) {
	resultPtr = *((Tcl_Obj **) ((char *)recordPtr+optionPtr->specPtr->objOffset));
    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.
	     */

2087
2088
2089
2090
2091
2092
2093
2094

2095
2096

2097
2098
2099
2100
2101
2102
2103
2134
2135
2136
2137
2138
2139
2140

2141
2142

2143
2144
2145
2146
2147
2148
2149
2150







-
+

-
+








    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_NewIntObj(tablePtr->refCount));
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewWideIntObj(tablePtr->numOptions));
			Tcl_NewIntObj(tablePtr->numOptions));
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
			tablePtr->options[0].specPtr->optionName, -1));
	    }
	    break;
	}
    }
    return objPtr;
Changes to generic/tkConsole.c.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







 * 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;
    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.
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+







/*
 * 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. */
    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. */
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234







-
+







    ConsoleInfo *info;
    Tcl_Channel consoleChannel;

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
    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.
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453







-
+







    if (mainWindow) {
	Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
		ConsoleEventProc, info);
	info->refCount++;
    }

    Tcl_Preserve(consoleInterp);
    result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
    result = Tcl_EvalEx(consoleInterp, "source -encoding utf-8 $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);
Changes to generic/tkCursor.c.
10
11
12
13
14
15
16




17
18
19
20
21
22
23
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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * A TkCursor structure exists for each cursor that is currently active. Each
 * structure is indexed with two hash tables defined below. One of the tables
 * is cursorIdTable, and the other is either cursorNameTable or
 * cursorDataTable, each of which are stored in the TkDisplay structure for
 * the current thread.
 */
421
422
423
424
425
426
427
428

429
430
431

432
433
434
435
436
437
438
425
426
427
428
429
430
431

432
433
434

435
436
437
438
439
440
441
442







-
+


-
+







    TkCursor *cursorPtr;
    TkDisplay *dispPtr;

    dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
    printid:
	sprintf(dispPtr->cursorString, "cursor id 0x%" TCL_Z_MODIFIER "x", (size_t)cursor);
	snprintf(dispPtr->cursorString, sizeof(dispPtr->cursorString), "cursor id 0x%" TCL_Z_MODIFIER "x", (size_t)cursor);
	return dispPtr->cursorString;
    }
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, cursor);
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
    if (idHashPtr == NULL) {
	goto printid;
    }
    cursorPtr = (TkCursor *)Tcl_GetHashValue(idHashPtr);
    if (cursorPtr->otherTable != &dispPtr->cursorNameTable) {
	goto printid;
    }
513
514
515
516
517
518
519
520

521
522
523
524
525
526
527
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);
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeCursor received unknown cursor argument");
    }
    FreeCursor((TkCursor *)Tcl_GetHashValue(idHashPtr));
}

/*
858
859
860
861
862
863
864
865

866
867

868
869
870
871
872
873
874
875
876
877
878
879
880
862
863
864
865
866
867
868

869
870

871
872
873
874
875
876
877
878
879
880
881
882
883
884







-
+

-
+













	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_NewIntObj(cursorPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(cursorPtr->objRefCount));
		    Tcl_NewIntObj(cursorPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkDList.h.
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17









-
+







/*
 * 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.
 * Copyright (c) 2018 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
Changes to generic/tkDecls.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
1
2
3
4
5

6
7
8
9
10
11
12
13
14
15
16
17
18
19








20
21
22
23
24
25
26





-
+













-
-
-
-
-
-
-
-







/*
 * tkDecls.h --
 *
 *	Declarations of functions in the platform independent public Tcl API.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * 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.
 */

#ifndef _TKDECLS
#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. */
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+







/* 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,
EXTERN CONST86 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,
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143







-
+







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 argc, CONST84 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,
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225







-
+







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);
EXTERN CONST84_RETURN 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,
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312

313
314
315
316
317
318
319
277
278
279
280
281
282
283


284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302

303
304
305
306
307
308
309
310







-
-
+
















-
+

-
+







				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);
EXTERN 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);
EXTERN CONST84_RETURN char * Tk_GetAtomName(Tk_Window tkwin, Atom atom);
/* 84 */
EXTERN const char *	Tk_GetBinding(Tcl_Interp *interp,
EXTERN CONST84_RETURN 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,
351
352
353
354
355
356
357
358

359
360

361
362
363
364
365
366
367
342
343
344
345
346
347
348

349
350

351
352
353
354
355
356
357
358







-
+

-
+







				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,
EXTERN ClientData	Tk_GetImageMasterData(Tcl_Interp *interp,
				const char *name,
				const Tk_ImageType **typePtrPtr);
				CONST86 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,
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386







-
+







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,
				CONST84 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,
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412







-
+







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,
EXTERN void		Tk_ImageChanged(Tk_ImageMaster 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 */
443
444
445
446
447
448
449
450

451
452

453
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
434
435
436
437
438
439
440

441
442

443
444

445
446

447
448

449
450

451
452
453

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







-
+

-
+

-
+

-
+

-
+

-
+
+

-
+

-
+

-
+

-
+

-
+








-
+


-
-
+



-
-
+










-
-
+





-
-
+







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);
EXTERN CONST84_RETURN char * Tk_NameOf3DBorder(Tk_3DBorder border);
/* 131 */
EXTERN const char *	Tk_NameOfAnchor(Tk_Anchor anchor);
EXTERN CONST84_RETURN char * Tk_NameOfAnchor(Tk_Anchor anchor);
/* 132 */
EXTERN const char *	Tk_NameOfBitmap(Display *display, Pixmap bitmap);
EXTERN CONST84_RETURN char * Tk_NameOfBitmap(Display *display, Pixmap bitmap);
/* 133 */
EXTERN const char *	Tk_NameOfCapStyle(int cap);
EXTERN CONST84_RETURN char * Tk_NameOfCapStyle(int cap);
/* 134 */
EXTERN const char *	Tk_NameOfColor(XColor *colorPtr);
EXTERN CONST84_RETURN char * Tk_NameOfColor(XColor *colorPtr);
/* 135 */
EXTERN const char *	Tk_NameOfCursor(Display *display, Tk_Cursor cursor);
EXTERN CONST84_RETURN char * Tk_NameOfCursor(Display *display,
				Tk_Cursor cursor);
/* 136 */
EXTERN const char *	Tk_NameOfFont(Tk_Font font);
EXTERN CONST84_RETURN char * Tk_NameOfFont(Tk_Font font);
/* 137 */
EXTERN const char *	Tk_NameOfImage(Tk_ImageModel model);
EXTERN CONST84_RETURN char * Tk_NameOfImage(Tk_ImageMaster model);
/* 138 */
EXTERN const char *	Tk_NameOfJoinStyle(int join);
EXTERN CONST84_RETURN char * Tk_NameOfJoinStyle(int join);
/* 139 */
EXTERN const char *	Tk_NameOfJustify(Tk_Justify justify);
EXTERN CONST84_RETURN char * Tk_NameOfJustify(Tk_Justify justify);
/* 140 */
EXTERN const char *	Tk_NameOfRelief(int relief);
EXTERN CONST84_RETURN 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,
				int *argcPtr, CONST84 char **argv,
				const Tk_ArgvInfo *argTable, int flags);
/* 144 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
EXTERN 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(
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);
/* 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,
EXTERN 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,
EXTERN 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 */
628
629
630
631
632
633
634
635

636
637
638
639
640
641
642
616
617
618
619
620
621
622

623
624
625
626
627
628
629
630







-
+







				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,
EXTERN void		Tk_FreeConfigOptions(char *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 */
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
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







-
+




-
+



















-
+








-
+







/* 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,
EXTERN Tcl_Obj *	Tk_GetOptionInfo(Tcl_Interp *interp, char *recordPtr,
				Tk_OptionTable optionTable, Tcl_Obj *namePtr,
				Tk_Window tkwin);
/* 205 */
EXTERN Tcl_Obj *	Tk_GetOptionValue(Tcl_Interp *interp,
				void *recordPtr, Tk_OptionTable optionTable,
				char *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,
EXTERN int		Tk_InitOptions(Tcl_Interp *interp, char *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,
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);
/* 215 */
EXTERN void		Tk_InitConsoleChannels(Tcl_Interp *interp);
/* 216 */
EXTERN int		Tk_CreateConsoleWindow(Tcl_Interp *interp);
784
785
786
787
788
789
790
791
792

793
794
795
796
797

798
799
800
801
802
803
804
772
773
774
775
776
777
778


779
780
781
782


783
784
785
786
787
788
789
790







-
-
+



-
-
+







/* 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,
EXTERN 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,
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);
/* 248 */
EXTERN int		Tk_CollapseMotionEvents(Display *display,
				int collapse);
/* 249 */
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
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







-
+




-
+





-
+



-
+







/* 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_StyledElement element, char *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_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);
/* 263 */
EXTERN int		Tk_GetElementBorderWidth(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_StyledElement element, char *recordPtr,
				Tk_Window tkwin);
/* 264 */
EXTERN void		Tk_DrawElement(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_StyledElement element, char *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,
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
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







-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/* 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 */
/* Slot 274 is reserved */
EXTERN int		Tk_AlwaysShowSelection(Tk_Window tkwin);
/* 275 */
/* Slot 275 is reserved */
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);
/* Slot 276 is reserved */
/* Slot 277 is reserved */
/* Slot 278 is reserved */
/* Slot 279 is reserved */
/* Slot 280 is reserved */
/* Slot 281 is reserved */
/* Slot 282 is reserved */
/* Slot 283 is reserved */
/* Slot 284 is reserved */
/* Slot 285 is reserved */
/* Slot 286 is reserved */
/* Slot 287 is reserved */
/* Slot 288 is reserved */
/* Slot 289 is reserved */
/* 290 */
EXTERN void		TkUnusedStubEntry(void);

typedef struct {
    const struct TkPlatStubs *tkPlatStubs;
    const struct TkIntStubs *tkIntStubs;
    const struct TkIntPlatStubs *tkIntPlatStubs;
    const struct TkIntXlibStubs *tkIntXlibStubs;
} TkStubHooks;
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
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







-
+









-
+







    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 */
    CONST86 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 */
    int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const 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 *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 */
956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
945
946
947
948
949
950
951

952
953
954
955
956
957
958
959







-
+







    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 */
    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 */
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
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







-
+





-
-
+
+













-
+









-
+








-
+












-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+


-
+

-
+







    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 */
    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 */
    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 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 */
    ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, const char *name, CONST86 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_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_ImageModel model, int x, int y, int width, int height, int imageWidth, int imageHeight); /* 117 */
    void (*tk_ImageChanged) (Tk_ImageMaster 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 */
    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 model); /* 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, 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_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const 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 */
    TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */
    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 */
    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 */
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
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







-
+








-
-
+
+





-
-
+
+

-
+







    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_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, 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 */
    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, 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 */
    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, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 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); /* 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 */
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
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







-
-
+
+













-
-
-
-
+
+
+
+









-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    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 */
    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, 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 */
    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) (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 */
    void (*reserved274)(void);
    void (*reserved275)(void);
    void (*reserved276)(void);
    void (*reserved277)(void);
    void (*reserved278)(void);
    void (*reserved279)(void);
    void (*reserved280)(void);
    void (*reserved281)(void);
    void (*reserved282)(void);
    void (*reserved283)(void);
    void (*reserved284)(void);
    void (*reserved285)(void);
    void (*reserved286)(void);
    void (*reserved287)(void);
    void (*reserved288)(void);
    void (*reserved289)(void);
    void (*tkUnusedStubEntry) (void); /* 290 */
} TkStubs;

extern const TkStubs *tkStubsPtr;

#ifdef __cplusplus
}
#endif
1391
1392
1393
1394
1395
1396
1397
1398
1399


1400
1401
1402
1403
1404
1405
1406
1391
1392
1393
1394
1395
1396
1397


1398
1399
1400
1401
1402
1403
1404
1405
1406







-
-
+
+







	(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_GetImageMasterData \
	(tkStubsPtr->tk_GetImageMasterData) /* 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 \
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
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







-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










-
-
-
-
-
-
-
-
+






-
-
+
+
-
-
-
-
-
-
-
-
-




+
+

	(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 */
/* Slot 274 is reserved */
/* Slot 275 is reserved */
/* Slot 276 is reserved */
/* Slot 277 is reserved */
/* Slot 278 is reserved */
/* Slot 279 is reserved */
/* Slot 280 is reserved */
/* Slot 281 is reserved */
/* Slot 282 is reserved */
/* Slot 283 is reserved */
/* Slot 284 is reserved */
/* Slot 285 is reserved */
/* Slot 286 is reserved */
/* Slot 287 is reserved */
/* Slot 288 is reserved */
/* Slot 289 is reserved */
#define TkUnusedStubEntry \
	(tkStubsPtr->tkUnusedStubEntry) /* 290 */

#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
#define Tk_GetImageModelData Tk_GetImageMasterData

#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


#undef Tk_FreeStyleFromObj
#define Tk_FreeStyleFromObj(objPtr) ((void)(objPtr))
#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

#undef TkUnusedStubEntry

#endif /* _TKDECLS */
Changes to generic/tkEntry.c.
15
16
17
18
19
20
21




22
23
24
25
26
27
28
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32







+
+
+
+







 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkEntry.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following macro defines how many extra pixels to leave on each side of
 * the text in the entry.
 */

#define XPAD 1
#define YPAD 1
59
60
61
62
63
64
65
66

67
68
69

70
71

72
73

74
75

76
77
78
79
80



81
82
83


84
85
86


87
88

89
90

91
92

93
94
95

96
97

98
99
100


101
102

103
104
105
106



107
108

109
110
111

112
113

114
115

116
117
118

119
120

121
122
123
124
125
126
127
128
129
130



131
132

133
134

135
136
137
138


139
140
141

142
143
144

145
146
147

148
149
150

151
152
153

154
155
156

157
158
159

160
161

162
163

164
165

166
167

168
169
170
171
172
173
174
63
64
65
66
67
68
69

70
71
72

73
74

75
76

77
78

79
80
81



82
83
84
85


86
87
88


89
90
91

92
93

94
95

96
97
98

99
100

101
102


103
104
105

106
107



108
109
110
111

112
113
114

115
116

117
118

119
120
121

122
123

124






125



126
127
128
129

130
131

132
133
134


135
136
137
138

139
140
141

142
143
144

145
146
147

148
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 Entry objv parsing.
 */

static const Tk_OptionSpec entryOptSpec[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_ENTRY_BG_COLOR, TCL_INDEX_NONE, offsetof(Entry, normalBorder),
	DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
	DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, 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, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
	Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
	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},
	"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, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
	Tk_Offset(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, TCL_INDEX_NONE, offsetof(Entry, tkfont), 0, 0, 0},
	DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, TCL_INDEX_NONE, offsetof(Entry, fgColorPtr), 0, 0, 0},
	DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(Entry, highlightBgColorPtr), 0, 0, 0},
	-1, Tk_Offset(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Entry, highlightColorPtr), 0, 0, 0},
	DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
	DEF_ENTRY_INSERT_BG, -1, Tk_Offset(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},
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1,
	Tk_Offset(Entry, insertBorderWidth), 0,
	DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(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},
	DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
	DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
	NULL, 0, -1, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
	DEF_ENTRY_JUSTIFY, -1, Tk_Offset(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},
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
	Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
	DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(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),
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
	Tk_Offset(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),
	DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(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),
	DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, TCL_INDEX_NONE, offsetof(Entry, state),
	DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Entry, 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, TCL_INDEX_NONE, offsetof(Entry, textVarName),
	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, TCL_INDEX_NONE, offsetof(Entry, validate),
	DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-validatecommand", 0},
	NULL, 0, -1, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, TCL_INDEX_NONE, offsetof(Entry, prefWidth), 0, 0, 0},
	DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Entry, scrollCmd),
	DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 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
180
181
182
183
184
185
186

187
188
189

190
191
192

193
194

195
196

197
198

199
200
201

202
203
204

205
206

207
208

209
210
211

212
213
214



215
216
217
218


219
220
221


222
223
224

225
226

227
228

229
230

231
232
233

234
235
236

237
238

239
240


241
242
243

244
245

246
247



248
249
250
251

252
253
254

255
256

257
258

259
260
261

262
263

264






265

266
267



268
269
270
271

272
273
274

275
276
277

278
279
280


281
282
283
284

285
286
287

288
289
290

291
292
293

294
295
296

297
298

299
300
301

302
303

304
305
306

307
308

309
310

311
312

313
314

315
316
317
318
319
320
321
322







-
+


-
+


-
+

-
+

-
+

-
+


-
+


-
+

-
+

-
+


-
+


-
-
-
+
+
+

-
-
+
+

-
-
+
+

-
+

-
+

-
+

-
+


-
+


-
+

-
+

-
-
+
+

-
+

-
+

-
-
-
+
+
+

-
+


-
+

-
+

-
+


-
+

-
+
-
-
-
-
-
-

-
+

-
-
-
+
+
+

-
+


-
+


-
+


-
-
+
+


-
+


-
+


-
+


-
+


-
+

-
+


-
+

-
+


-
+

-
+

-
+

-
+

-
+







#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),
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(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),
	DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
	DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-buttonbackground", "buttonBackground", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(Spinbox, buttonBorder),
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(Spinbox, buttonBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_CURSOR, "-buttoncursor", "buttonCursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(Spinbox, bCursor),
	DEF_BUTTON_CURSOR, -1, Tk_Offset(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},
	DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, bdRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-buttonuprelief", "buttonUpRelief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(Spinbox, buRelief), 0, 0, 0},
	DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, buRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_SPINBOX_CMD, TCL_INDEX_NONE, offsetof(Spinbox, command),
	DEF_SPINBOX_CMD, -1, Tk_Offset(Spinbox, command),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, 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, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
	Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
	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},
	"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, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
	Tk_Offset(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, TCL_INDEX_NONE, offsetof(Entry, tkfont), 0, 0, 0},
	DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, TCL_INDEX_NONE, offsetof(Entry, fgColorPtr), 0, 0, 0},
	DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_STRING, "-format", "format", "Format",
	DEF_SPINBOX_FORMAT, TCL_INDEX_NONE, offsetof(Spinbox, reqFormat),
	DEF_SPINBOX_FORMAT, -1, Tk_Offset(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},
	DEF_SPINBOX_FROM, -1, Tk_Offset(Spinbox, fromValue), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(Entry, highlightBgColorPtr), 0, 0, 0},
	-1, Tk_Offset(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Entry, highlightColorPtr), 0, 0, 0},
	DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	DEF_SPINBOX_INCREMENT, TCL_INDEX_NONE, offsetof(Spinbox, increment), 0, 0, 0},
	DEF_SPINBOX_INCREMENT, -1, Tk_Offset(Spinbox, increment), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
	DEF_ENTRY_INSERT_BG, -1, Tk_Offset(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},
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1,
	Tk_Offset(Entry, insertBorderWidth), 0,
	DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(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},
	DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
	DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
	NULL, 0, -1, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
	DEF_ENTRY_JUSTIFY, -1, Tk_Offset(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},
	DEF_ENTRY_RELIEF, -1, Tk_Offset(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},
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
	Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SPINBOX_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(Spinbox, repeatDelay),
	DEF_SPINBOX_REPEAT_DELAY, -1, Tk_Offset(Spinbox, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SPINBOX_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(Spinbox, repeatInterval),
	DEF_SPINBOX_REPEAT_INTERVAL, -1, Tk_Offset(Spinbox, repeatInterval),
	0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(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),
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
	Tk_Offset(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),
	DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(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),
	DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Entry, 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, TCL_INDEX_NONE, offsetof(Entry, textVarName),
	DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(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},
	DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	DEF_ENTRY_VALIDATE, TCL_INDEX_NONE, offsetof(Entry, validate),
	DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-values", "values", "Values",
	DEF_SPINBOX_VALUES, TCL_INDEX_NONE, offsetof(Spinbox, valueStr),
	DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-validatecommand", 0},
	NULL, 0, -1, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, TCL_INDEX_NONE, offsetof(Entry, prefWidth), 0, 0, 0},
	DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
	DEF_SPINBOX_WRAP, TCL_INDEX_NONE, offsetof(Spinbox, wrap), 0, 0, 0},
	DEF_SPINBOX_WRAP, -1, Tk_Offset(Spinbox, wrap), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Entry, scrollCmd),
	DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * The following tables define the entry widget commands (and sub-commands)
 * and map the indexes into the string tables into enumerated types used to
 * dispatch the entry widget command.
 */
399
400
401
402
403
404
405
406
407
408
409
410





411
412

413
414
415
416
417



418
419
420
421
422


423
424
425
426
427
428

429
430

431
432
433
434
435
436

437
438
439

440
441
442


443
444
445
446
447
448

449
450
451
452
453
454
455
391
392
393
394
395
396
397





398
399
400
401
402
403

404
405
406



407
408
409
410
411
412


413
414
415
416
417
418
419

420
421

422
423
424
425
426
427

428
429
430

431
432


433
434
435
436
437
438
439

440
441
442
443
444
445
446
447







-
-
-
-
-
+
+
+
+
+

-
+


-
-
-
+
+
+



-
-
+
+





-
+

-
+





-
+


-
+

-
-
+
+





-
+








/*
 * 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 int		DeleteChars(Entry *entryPtr, int index, int count);
static Tcl_FreeProc	DestroyEntry;
static void		DisplayEntry(void *clientData);
static void		EntryBlinkProc(void *clientData);
static void		EntryCmdDeletedProc(void *clientData);
static void		EntryComputeGeometry(Entry *entryPtr);
static void		EntryEventProc(ClientData clientData,
static void		EntryEventProc(void *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 int		EntryFetchSelection(void *clientData, int offset,
			    char *buffer, int maxBytes);
static void		EntryLostSelection(void *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,
static void		EntrySelectTo(Entry *entryPtr, int index);
static char *		EntryTextVarProc(void *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);
			    const char *newStr, int index, int type);
static void		ExpandPercents(Entry *entryPtr, const char *before,
			    const char *change, const char *newStr, TkSizeT index,
			    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,
static int		EntryWidgetObjCmd(void *clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		EntryWorldChanged(ClientData instanceData);
static void		EntryWorldChanged(void *instanceData);
static int		GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr,
			    Tcl_Obj *indexObj, TkSizeT *indexPtr);
static int		InsertChars(Entry *entryPtr, TkSizeT index, const char *string);
			    Tcl_Obj *indexObj, int *indexPtr);
static int		InsertChars(Entry *entryPtr, int index, const char *string);

/*
 * These forward declarations are the spinbox specific ones:
 */

static int		SpinboxWidgetObjCmd(ClientData clientData,
static int		SpinboxWidgetObjCmd(void *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);

480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494







-
+








-







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_EntryObjCmd(
    ClientData dummy,	/* NULL. */
    TCL_UNUSED(void *),
    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),
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
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







-
-
+
+














-
-















-
+






-
+







	    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->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;

    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)
    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_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EntryWidgetObjCmd --
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597







-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
EntryWidgetObjCmd(
    ClientData clientData,	/* Information about entry widget. */
    void *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;
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
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







-
+











-
+



-
-
-
-
+
+
+
+










-
+









-
+













-
+
















-
+













-
+















-
+









-
+




-
+







    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum entryCmd) cmdIndex) {
    case COMMAND_BBOX: {
	TkSizeT index;
	int 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)) {
	if ((index == entryPtr->numChars) && (index > 0)) {
	    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);
	bbox[0] = Tcl_NewIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewIntObj(width);
	bbox[3] = Tcl_NewIntObj(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,
	objPtr = Tk_GetOptionValue(interp, (char *) 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,
	    objPtr = Tk_GetOptionInfo(interp, (char *) 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 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)) {
	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_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, TCL_INDEX_NONE));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1));
	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;
	int 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));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	break;
    }

    case COMMAND_INSERT: {
	TkSizeT index;
	int index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
790
791
792
793
794
795
796
797

798
799
800
801
802
803
804
779
780
781
782
783
784
785

786
787
788
789
790
791
792
793







-
+







		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case COMMAND_SELECTION: {
	TkSizeT index, index2;
	int index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*
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
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







-
-
+
+



-
+

-
+
















-
-
-
+
+
+







		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;
	    if (entryPtr->selectFirst >= 0) {
		int half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1 ) {
		if (index < half1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1 ) {
		} 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 != TCL_INDEX_NONE) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    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");
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
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







-
+















-
-
-
+
+
+








	case SELECTION_PRESENT:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp,
		    Tcl_NewWideIntObj(entryPtr->selectFirst != TCL_INDEX_NONE));
		    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, 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;
	    if (index >= index2) {
		entryPtr->selectFirst = -1;
		entryPtr->selectLast = -1;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && (entryPtr->exportSelection)
		    && (!Tcl_IsSafe(entryPtr->interp))) {
944
945
946
947
948
949
950
951

952
953
954
955
956
957
958
933
934
935
936
937
938
939

940
941
942
943
944
945
946
947







-
+







	    entryPtr->validate = selIndex;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case COMMAND_XVIEW: {
	TkSizeT index;
	int index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);
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
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







-
-

















+
+


-
+


-
+







	} else {
	    double fraction;
	    int count;

	    index = entryPtr->leftIndex;
	    switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
		    &count)) {
	    case TK_SCROLL_ERROR:
		goto error;
	    case TK_SCROLL_MOVETO:
		index = (int) ((fraction * entryPtr->numChars) + 0.5);
		break;
	    case TK_SCROLL_PAGES: {
		int charsPerPage;

		charsPerPage = ((Tk_Width(entryPtr->tkwin)
			- 2 * entryPtr->inset) / entryPtr->avgWidth) - 2;
		if (charsPerPage < 1) {
		    charsPerPage = 1;
		}
		index += count * charsPerPage;
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;
	    default:
		goto error;
	    }
	}
	if (index + 1 >= entryPtr->numChars + 1) {
	if (index >= entryPtr->numChars) {
	    index = entryPtr->numChars - 1;
	}
	if ((int)index < 0) {
	if (index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;
1031
1032
1033
1034
1035
1036
1037
1038

1039
1040
1041
1042
1043
1044
1045
1020
1021
1022
1023
1024
1025
1026

1027
1028
1029
1030
1031
1032
1033
1034







-
+







 *	Everything associated with the entry is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyEntry(
    void *memPtr)		/* Info about entry widget. */
    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.
     */
1119
1120
1121
1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122







+







    char *oldFormat = NULL;
    int error;
    int oldExport = 0;
    int valuesChanged = 0;
    double oldFrom = 0.0;
    double oldTo = 0.0;
    int code;
    size_t formatSpace = TCL_DOUBLE_SPACE;

    /*
     * Eliminate any existing trace on a variable monitored by the entry.
     */

    if ((entryPtr->textVarName != NULL)
	    && (entryPtr->flags & ENTRY_VAR_TRACED)) {
1151
1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
1141
1142
1143
1144
1145
1146
1147

1148
1149
1150
1151
1152
1153
1154
1155







-
+








    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, entryPtr,
	    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
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







-
-
+
+
-
-
+
-
-
+
-
-
-
+
+
+









-
+







	}
	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.
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-to value must be greater than -from value",
                 */

			-1));
                double tmpFromTo = sbPtr->fromValue;

		Tcl_SetErrorCode(interp, "TK", "SPINBOX", "RANGE_SANITY",
                sbPtr->fromValue = sbPtr->toValue;
                sbPtr->toValue = tmpFromTo;
            }
			NULL);
		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;
		size_t formatLen;
		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\"",
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
1261







-
+







		    Tcl_DecrRefCount(sbPtr->listObj);
		}
		sbPtr->listObj = NULL;
		if (sbPtr->valueStr != NULL) {
		    Tcl_Obj *newObjPtr;
		    int nelems;

		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, TCL_INDEX_NONE);
		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, -1);
		    if (Tcl_ListObjLength(interp, newObjPtr, &nelems)
			    != TCL_OK) {
			valuesChanged = -1;
			continue;
		    }
		    sbPtr->listObj = newObjPtr;
		    Tcl_IncrRefCount(sbPtr->listObj);
1294
1295
1296
1297
1298
1299
1300
1301

1302
1303
1304
1305
1306
1307
1308
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296







-
+








	/*
	 * Claim the selection if we've suddenly started exporting it.
	 */

	if (entryPtr->exportSelection && (!oldExport)
		&& (!Tcl_IsSafe(entryPtr->interp))
		&& (entryPtr->selectFirst != TCL_INDEX_NONE)
		&& (entryPtr->selectFirst != -1)
		&& !(entryPtr->flags & GOT_SELECTION)) {
	    Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		    entryPtr);
	    entryPtr->flags |= GOT_SELECTION;
	}

	/*
1386
1387
1388
1389
1390
1391
1392
1393

1394
1395
1396
1397
1398
1399
1400
1374
1375
1376
1377
1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
1388







-
+







		/* 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);
	    snprintf(sbPtr->formatBuf, formatSpace, 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);
1443
1444
1445
1446
1447
1448
1449
1450

1451
1452
1453
1454
1455
1456
1457
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440
1441
1442
1443
1444
1445







-
+







 *	Entry will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
EntryWorldChanged(
    ClientData instanceData)	/* Information about widget. */
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    unsigned long mask;
    Tk_3DBorder border;
    XColor *colorPtr;
    Entry *entryPtr = (Entry *)instanceData;
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
1491
1492
1493
1494
1495
1496
1497










1498
1499


1500
1501
1502
1503
1504
1505
1506







-
-
-
-
-
-
-
-
-
-


-
-







    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);
    }
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565



1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1532
1533
1534
1535
1536
1537
1538



1539
1540
1541
1542




1543
1544
1545
1546
1547
1548
1549







-
-
-
+
+
+

-
-
-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawEntryBorderAndFocus(
    Entry *entryPtr,
    Drawable pixmap,
    int isSpinbox)
    TCL_UNUSED(Entry *),
    TCL_UNUSED(Drawable),
    TCL_UNUSED(int))
{
    (void)entryPtr;
    (void)pixmap;
    (void)isSpinbox;

    return 0;
}

/*
 *--------------------------------------------------------------
 *
 * TkpDrawSpinboxButtons --
1587
1588
1589
1590
1591
1592
1593
1594
1595


1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1559
1560
1561
1562
1563
1564
1565


1566
1567
1568



1569
1570
1571
1572
1573
1574
1575







-
-
+
+

-
-
-







 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkpDrawSpinboxButtons(
    Spinbox *sbPtr,
    Pixmap pixmap)
    TCL_UNUSED(Spinbox *),
    TCL_UNUSED(Pixmap))
{
    (void)sbPtr;
    (void)pixmap;

    return 0;
}
#endif /* Not MAC_OSX_TK */

/*
 *--------------------------------------------------------------
 *
1615
1616
1617
1618
1619
1620
1621
1622

1623
1624
1625
1626
1627
1628
1629
1584
1585
1586
1587
1588
1589
1590

1591
1592
1593
1594
1595
1596
1597
1598







-
+







 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

static void
DisplayEntry(
    ClientData clientData)	/* Information about window. */
    void *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;
1680
1681
1682
1683
1684
1685
1686
1687

1688
1689
1690
1691
1692
1693
1694
1649
1650
1651
1652
1653
1654
1655

1656
1657
1658
1659
1660
1661
1662
1663







-
+







    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)) {
    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
1674
1675
1676
1677
1678
1679
1680

1681
1682
1683
1684
1685
1686
1687
1688







-
+







    } 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)) {
	    && (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;
	}
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
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







-
+













-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+

-
-
-
+
+
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
+
+
+

-
-
-
+
+
+
-







    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->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);
	    }
	}
    }

    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)) {
    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selTextGC != entryPtr->textGC)
	    && (entryPtr->selectFirst < entryPtr->selectLast)) {

	    /*
	     * Draw the selected and unselected portions separately.
	     */
	/*
	 * Draw the selected and unselected portions separately.
	 */

	    TkSizeT selFirst;
	int 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 {
	if (entryPtr->selectFirst < entryPtr->leftIndex) {
	    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
             */
        /*
         * Draw the entire visible text
         */

	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    entryPtr->leftIndex, entryPtr->numChars);
	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;

	/*
1969
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
1925
1926
1927
1928
1929
1930
1931

1932
1933
1934
1935
1936
1937
1938
1939







-
+







 */

static void
EntryComputeGeometry(
    Entry *entryPtr)		/* Widget record for entry. */
{
    int totalLength, overflow, rightX;
    TkSizeT maxOffScreen;
    int maxOffScreen;
    int height, width, i;
    Tk_FontMetrics fm;
    char *p;

    if (entryPtr->displayString != entryPtr->string) {
	ckfree((char *)entryPtr->displayString);
	entryPtr->displayString = entryPtr->string;
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
1960
1961
1962
1963
1964
1965
1966

1967
1968
1969
1970
1971
1972
1973




















































1974
1975
1976
1977
1978
1979
1980







-
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	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; ) {
	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;

2105
2106
2107
2108
2109
2110
2111
2112

2113
2114
2115
2116
2117
2118
2119
2009
2010
2011
2012
2013
2014
2015

2016
2017
2018
2019
2020
2021
2022
2023







-
+








	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) {
	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;
    }
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
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







-
+




+
-
+
+




-
+







 *
 *----------------------------------------------------------------------
 */

static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    TkSizeT index,			/* Add the new elements before this character
    int index,			/* Add the new elements before this character
				 * index. */
    const char *value)		/* New characters to add (NULL-terminated
				 * string). */
{
    ptrdiff_t byteIndex;
    size_t byteIndex, byteCount, newByteCount, oldChars, charsAdded;
    size_t byteCount, newByteCount;
    int oldChars, charsAdded;
    const char *string;
    char *newStr;

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteIndex = TkUtfAtIndex(string, index) - string;
    byteCount = strlen(value);
    if (byteCount == 0) {
	return TCL_OK;
    }

    newByteCount = entryPtr->numBytes + byteCount + 1;
    newStr = (char *)ckalloc(newByteCount);
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
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







+
+









-
+
















-
+


-
+


-
+


-
+


-
+







	return TCL_OK;
    }

    ckfree((char *)string);
    entryPtr->string = newStr;

    /*
     * ??? Is this construction still needed with Tcl_NumUtfChars ???
     *
     * The following construction is used because inserting improperly formed
     * UTF-8 sequences between other improperly formed UTF-8 sequences could
     * result in actually forming valid UTF-8 sequences; the number of
     * characters added may not be Tcl_NumUtfChars(string, -1), because of
     * context. The actual number of characters added is how many characters
     * are in the string now minus the number that used to be there.
     */

    oldChars = entryPtr->numChars;
    entryPtr->numChars = Tcl_NumUtfChars(newStr, TCL_INDEX_NONE);
    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 + 1 >= index + 1) {
    if (entryPtr->selectFirst >= index) {
	entryPtr->selectFirst += charsAdded;
    }
    if (entryPtr->selectLast + 1 > index + 1) {
    if (entryPtr->selectLast > index) {
	entryPtr->selectLast += charsAdded;
    }
    if ((entryPtr->selectAnchor + 1 > index + 1) || (entryPtr->selectFirst + 1 >= index + 1)) {
    if ((entryPtr->selectAnchor > index) || (entryPtr->selectFirst >= index)) {
	entryPtr->selectAnchor += charsAdded;
    }
    if (entryPtr->leftIndex + 1 > index + 1) {
    if (entryPtr->leftIndex > index) {
	entryPtr->leftIndex += charsAdded;
    }
    if (entryPtr->insertPos + 1 >= index + 1) {
    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
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







-
-
+
+





-
+


-
+




-
-
+
+







 *
 *----------------------------------------------------------------------
 */

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 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 + 1 > entryPtr->numChars + 1) {
    if (index + count > entryPtr->numChars) {
	count = entryPtr->numChars - index;
    }
    if ((int)count <= 0) {
    if (count <= 0) {
	return TCL_OK;
    }

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string+byteIndex);
    byteIndex = TkUtfAtIndex(string, index) - string;
    byteCount = TkUtfAtIndex(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);
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
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







-
-
+
+





-
-
+
+





-
-
-
+
+
+

-
-
+
+





-
-
+
+





-
-
+
+








    /*
     * 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) {
    if (entryPtr->selectFirst >= index) {
	if (entryPtr->selectFirst >= index + count) {
	    entryPtr->selectFirst -= count;
	} else {
	    entryPtr->selectFirst = index;
	}
    }
    if (entryPtr->selectLast + 1 >= index + 1) {
	if (entryPtr->selectLast + 1 >= index + count + 1) {
    if (entryPtr->selectLast >= index) {
	if (entryPtr->selectLast >= index + count) {
	    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->selectLast <= entryPtr->selectFirst) {
	entryPtr->selectFirst = -1;
	entryPtr->selectLast = -1;
    }
    if (entryPtr->selectAnchor + 1 >= index + 1) {
	if (entryPtr->selectAnchor + 1 >= index + count + 1) {
    if (entryPtr->selectAnchor >= index) {
	if (entryPtr->selectAnchor >= index + count) {
	    entryPtr->selectAnchor -= count;
	} else {
	    entryPtr->selectAnchor = index;
	}
    }
    if (entryPtr->leftIndex + 1 > index + 1) {
	if (entryPtr->leftIndex + 1 >= index + count + 1) {
    if (entryPtr->leftIndex > index) {
	if (entryPtr->leftIndex >= index + count) {
	    entryPtr->leftIndex -= count;
	} else {
	    entryPtr->leftIndex = index;
	}
    }
    if (entryPtr->insertPos + 1 >= index + 1) {
	if (entryPtr->insertPos + 1 >= index + count + 1) {
    if (entryPtr->insertPos >= index) {
	if (entryPtr->insertPos >= index + count) {
	    entryPtr->insertPos -= count;
	} else {
	    entryPtr->insertPos = index;
	}
    }
    return EntryValueChanged(entryPtr, NULL);
}
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
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







-
-
-
-
-
+
+
+
+
+



-
-
+
+





-
+







    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) {
    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 + 1 >= entryPtr->numChars + 1) {
	if (entryPtr->numChars + 1 > 1) {
    if (entryPtr->leftIndex >= entryPtr->numChars) {
	if (entryPtr->numChars > 0) {
	    entryPtr->leftIndex = entryPtr->numChars - 1;
	} else {
	    entryPtr->leftIndex = 0;
	}
    }
    if (entryPtr->insertPos + 1 > entryPtr->numChars + 1) {
    if (entryPtr->insertPos > entryPtr->numChars) {
	entryPtr->insertPos = entryPtr->numChars;
    }

    entryPtr->flags |= UPDATE_SCROLLBAR;
    EntryComputeGeometry(entryPtr);
    EventuallyRedraw(entryPtr);
}
2547
2548
2549
2550
2551
2552
2553
2554

2555
2556
2557
2558
2559
2560
2561
2455
2456
2457
2458
2459
2460
2461

2462
2463
2464
2465
2466
2467
2468
2469







-
+







 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EntryEventProc(
    ClientData clientData,	/* Information about window. */
    void *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;
2590
2591
2592
2593
2594
2595
2596
2597

2598
2599
2600
2601
2602
2603
2604
2498
2499
2500
2501
2502
2503
2504

2505
2506
2507
2508
2509
2510
2511
2512







-
+







    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);
	    Tcl_EventuallyFree(clientData, DestroyEntry);
	}
	break;
    case ConfigureNotify:
	Tcl_Preserve(entryPtr);
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
2629
2630
2631
2632
2633
2634
2635
2636

2637
2638
2639
2640
2641
2642
2643
2537
2538
2539
2540
2541
2542
2543

2544
2545
2546
2547
2548
2549
2550
2551







-
+







 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
EntryCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
    void *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
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
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







-
+

-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-








+
+
+
+
+
+







-
+








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 */
    int *indexPtr)		/* Where to store converted character index */
{
    TkSizeT length, idx;
    const char *string;

    const char *string = Tcl_GetString(indexObj);
    size_t length = indexObj->length;
    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 'e':
	if (strncmp(string, "end", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->numChars;
	break;
    case 'i':
	if (strncmp(string, "insert", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->insertPos;
	break;
    case 's':
	if (entryPtr->selectFirst == TCL_INDEX_NONE) {
	if (entryPtr->selectFirst < 0) {
	    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);
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
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







-
+





+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-







	/*
	 * 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)) {
	if (roundUp && (*indexPtr < entryPtr->numChars)) {
	    *indexPtr += 1;
	}
	break;
    }
    default:
	if (Tcl_GetIntFromObj(NULL, indexObj, indexPtr) != TCL_OK) {
	    goto badIndex;
	}
	if (*indexPtr < 0){
	    *indexPtr = 0;
	} else if (*indexPtr > entryPtr->numChars) {
	    *indexPtr = entryPtr->numChars;
	}
    }
    return TCL_OK;

	  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;
  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;
}

/*
 *----------------------------------------------------------------------
 *
 * EntryScanTo --
 *
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
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







-
+














-
+



-
+







 */

static void
EntryScanTo(
    Entry *entryPtr,		/* Information about widget. */
    int x)			/* X-coordinate to use for scan operation. */
{
    TkSizeT newLeftIndex;
    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 + 1 >= entryPtr->numChars + 1) {
    if (newLeftIndex >= entryPtr->numChars) {
	newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars - 1;
	entryPtr->scanMarkX = x;
    }
    if (newLeftIndex == TCL_INDEX_NONE) {
    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
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







-
+


-
+
















-
+


-
+





-
-
+
+







 *
 *----------------------------------------------------------------------
 */

static void
EntrySelectTo(
    Entry *entryPtr,		/* Information about widget. */
    TkSizeT index)			/* Character index of element that is to
    int index)			/* Character index of element that is to
				 * become the "other" end of the selection. */
{
    TkSizeT newFirst, newLast;
    int 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) {
    if (entryPtr->selectAnchor > entryPtr->numChars) {
	entryPtr->selectAnchor = entryPtr->numChars;
    }
    if (entryPtr->selectAnchor + 1 <= index + 1) {
    if (entryPtr->selectAnchor <= index) {
	newFirst = entryPtr->selectAnchor;
	newLast = index;
    } else {
	newFirst = index;
	newLast = entryPtr->selectAnchor;
	if (newLast == TCL_INDEX_NONE) {
	    newFirst = newLast = TCL_INDEX_NONE;
	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
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







-
+

-
-
+
+


-
+



-
+



-
+




-
-
+
+

-
-
-



+
+
+







 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
EntryFetchSelection(
    ClientData clientData,	/* Information about entry widget. */
    TkSizeT offset,			/* Byte offset within selection of first
    void *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. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NUL character. */
{
    Entry *entryPtr = (Entry *)clientData;
    TkSizeT byteCount;
    int byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if ((entryPtr->selectFirst == TCL_INDEX_NONE) || (!entryPtr->exportSelection)
    if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection)
	    || Tcl_IsSafe(entryPtr->interp)) {
	return -1;
    }
    string = entryPtr->displayString;
    selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
    selStart = TkUtfAtIndex(string, entryPtr->selectFirst);
    selEnd = TkUtfAtIndex(selStart,
	    entryPtr->selectLast - entryPtr->selectFirst);
    if (selEnd <= selStart + offset) {
	return 0;
    }
    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }
    if (byteCount <= 0) {
	return 0;
    }
    memcpy(buffer, selStart + offset, byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
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
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







-
+












-
-
+
+

-
-
+
+







 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
EntryLostSelection(
    ClientData clientData)	/* Information about entry widget. */
    void *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
    if (TkpAlwaysShowSelection(entryPtr->tkwin)
	    && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	entryPtr->selectFirst = TCL_INDEX_NONE;
	entryPtr->selectLast = TCL_INDEX_NONE;
	entryPtr->selectFirst = -1;
	entryPtr->selectLast = -1;
	EventuallyRedraw(entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
3057
3058
3059
3060
3061
3062
3063
3064

3065
3066
3067
3068
3069
3070
3071
2968
2969
2970
2971
2972
2973
2974

2975
2976
2977
2978
2979
2980
2981
2982







-
+







    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) {
	if (charsInWindow < entryPtr->numChars) {
	    charsInWindow++;
	}
	charsInWindow -= entryPtr->leftIndex;
	if (charsInWindow == 0) {
	    charsInWindow = 1;
	}

3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123






3124
3125
3126
3127
3128
3129
3130
3022
3023
3024
3025
3026
3027
3028






3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041







-
-
-
-
-
-
+
+
+
+
+
+








    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_DStringAppend(&buf, entryPtr->scrollCmd, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, firstStr, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, lastStr, -1);
    code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 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);
    }
3148
3149
3150
3151
3152
3153
3154
3155

3156
3157
3158
3159
3160
3161
3162
3059
3060
3061
3062
3063
3064
3065

3066
3067
3068
3069
3070
3071
3072
3073







-
+







 *	function reschedules itself.
 *
 *----------------------------------------------------------------------
 */

static void
EntryBlinkProc(
    ClientData clientData)	/* Pointer to record describing entry. */
    void *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;
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
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







-
+

-
-
+
+




-
-















-
+






-
+







 *	The text displayed in the entry will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
EntryTextVarProc(
    ClientData clientData,	/* Information about button. */
    void *clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    TCL_UNUSED(const char *),
    TCL_UNUSED(const char *),
    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;
            void *probe = NULL;

            do {
                probe = Tcl_VarTraceInfo(interp,
                        entryPtr->textVarName,
                        TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                        EntryTextVarProc, probe);
                if (probe == (ClientData)entryPtr) {
                if (probe == (void *)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
3336
3337
3338
3339
3340
3341
3342
3343

3344
3345
3346
3347
3348
3349
3350
3245
3246
3247
3248
3249
3250
3251

3252
3253
3254
3255
3256
3257
3258
3259







-
+







     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);
    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) {
3393
3394
3395
3396
3397
3398
3399
3400

3401
3402
3403
3404
3405
3406
3407
3302
3303
3304
3305
3306
3307
3308

3309
3310
3311
3312
3313
3314
3315
3316







-
+








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 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;

3539
3540
3541
3542
3543
3544
3545
3546

3547
3548
3549
3550
3551
3552
3553
3448
3449
3450
3451
3452
3453
3454

3455
3456
3457
3458
3459
3460
3461
3462







-
+







     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 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;
3624
3625
3626
3627
3628
3629
3630
3631

3632
3633
3634
3635

3636
3637
3638
3639
3640
3641
3642
3533
3534
3535
3536
3537
3538
3539

3540
3541
3542
3543

3544
3545
3546
3547
3548
3549
3550
3551







-
+



-
+







		case VALIDATE_DELETE:
		    number = 0;
		    break;
		default:
		    number = -1;
		    break;
		}
		sprintf(numStorage, "%d", number);
		snprintf(numStorage, sizeof(numStorage), "%d", number);
		string = numStorage;
		break;
	    case 'i':		/* index of insert/delete */
		sprintf(numStorage, "%d", (int)index);
		snprintf(numStorage, sizeof(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;
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
3606
3607
3608
3609
3610
3611
3612

3613
3614
3615
3616
3617
3618
3619
3620
3621
3622

3623
3624
3625
3626
3627
3628
3629







-
+









-







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SpinboxObjCmd(
    ClientData dummy,	/* NULL. */
    TCL_UNUSED(void *),
    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),
3749
3750
3751
3752
3753
3754
3755
3756
3757


3758
3759
3760
3761
3762
3763
3764
3657
3658
3659
3660
3661
3662
3663


3664
3665
3666
3667
3668
3669
3670
3671
3672







-
-
+
+







	    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->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;
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
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







-
-















-
+








-
+







    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)
    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_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(entryPtr->tkwin);
    return TCL_ERROR;
}

3831
3832
3833
3834
3835
3836
3837
3838

3839
3840
3841
3842
3843
3844
3845
3737
3738
3739
3740
3741
3742
3743

3744
3745
3746
3747
3748
3749
3750
3751







-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
SpinboxWidgetObjCmd(
    ClientData clientData,	/* Information about spinbox widget. */
    void *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;
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
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







-
+











-
+



-
-
-
-
+
+
+
+










-
+









-
+












-
+


















-
+







    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum sbCmd) cmdIndex) {
    case SB_CMD_BBOX: {
	TkSizeT index;
	int 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)) {
	if ((index == entryPtr->numChars) && (index > 0)) {
	    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);
	bbox[0] = Tcl_NewIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewIntObj(width);
	bbox[3] = Tcl_NewIntObj(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,
	objPtr = Tk_GetOptionValue(interp, (char *) 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,
	    objPtr = Tk_GetOptionInfo(interp, (char *) 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 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)) {
	if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }
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
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







-
+









-
+




-
+







	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(selElementNames[elem], -1));
	}
	break;
    }

    case SB_CMD_INDEX: {
	TkSizeT index;
	int 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));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	break;
    }

    case SB_CMD_INSERT: {
	TkSizeT index;
	int index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
4065
4066
4067
4068
4069
4070
4071
4072

4073
4074
4075
4076
4077
4078
4079
3971
3972
3973
3974
3975
3976
3977

3978
3979
3980
3981
3982
3983
3984
3985







-
+







		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case SB_CMD_SELECTION: {
	TkSizeT index, index2;
	int index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*
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
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







-
-
+
+



-
+

-
+
















-
-
-
+
+
+







		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;
	    if (entryPtr->selectFirst >= 0) {
		int half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1) {
		if (index < half1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1) {
		} 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 != TCL_INDEX_NONE) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    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");
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
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







-
+















-
-
-
+
+
+








	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));
		    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,
		    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;
	    if (index >= index2) {
		entryPtr->selectFirst = -1;
		entryPtr->selectLast = -1;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && entryPtr->exportSelection
		    && (!Tcl_IsSafe(entryPtr->interp))) {
4259
4260
4261
4262
4263
4264
4265
4266

4267
4268
4269
4270
4271
4272
4273
4165
4166
4167
4168
4169
4170
4171

4172
4173
4174
4175
4176
4177
4178
4179







-
+







	}

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case SB_CMD_XVIEW: {
	TkSizeT index;
	int index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);
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
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







-
-

-
+
















+
+


-
+


-
+







	} 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);
		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;
	    default:
		goto error;
	    }
	}
	if (index + 1 >= entryPtr->numChars + 1) {
	if (index >= entryPtr->numChars) {
	    index = entryPtr->numChars - 1;
	}
	if (index == TCL_INDEX_NONE) {
	if (index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;
4423
4424
4425
4426
4427
4428
4429
4430

4431
4432
4433
4434
4435
4436

4437
4438
4439
4440
4441
4442
4443
4329
4330
4331
4332
4333
4334
4335

4336
4337
4338
4339
4340
4341

4342
4343
4344
4345
4346
4347
4348
4349







-
+





-
+







		/*
		 * 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;
		int 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);
		    bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
		    if ((length == elemLen) &&
			    (memcmp(bytes, entryPtr->string,
				    length) == 0)) {
			sbPtr->eIndex = i;
			break;
		    }
		}
4502
4503
4504
4505
4506
4507
4508
4509

4510
4511
4512
4513
4514
4515
4516
4408
4409
4410
4411
4412
4413
4414

4415
4416
4417
4418
4419
4420
4421
4422







-
+







		     * greater than the toValue, because the user may have
		     * manipulated the value by hand.
		     */

		    dvalue = sbPtr->toValue;
		}
	    }
	    sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);
	    snprintf(sbPtr->formatBuf, TCL_DOUBLE_SPACE, sbPtr->valueFormat, dvalue);
	    code = EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }
    if (code != TCL_OK) {
        return TCL_ERROR;
    }

4619
4620
4621
4622
4623
4624
4625
4626

4627
4628

4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4525
4526
4527
4528
4529
4530
4531

4532
4533

4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546







-
+

-
+












    if (afterDecimal > 0) {
	fDigits++;		/* Decimal point. */
    }
    if (mostSigDigit < 0) {
	fDigits++;		/* Zero to left of decimal point. */
    }
    if (fDigits <= eDigits) {
	sprintf(sbPtr->digitFormat, "%%.%df", afterDecimal);
	snprintf(sbPtr->digitFormat, sizeof(sbPtr->digitFormat), "%%.%df", afterDecimal);
    } else {
	sprintf(sbPtr->digitFormat, "%%.%de", numDigits-1);
	snprintf(sbPtr->digitFormat, sizeof(sbPtr->digitFormat), "%%.%de", numDigits-1);
    }
    sbPtr->valueFormat = sbPtr->digitFormat;
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkEntry.h.
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55

56
57

58
59

60
61
62
63
64
65
66
41
42
43
44
45
46
47

48
49
50
51
52
53
54

55
56

57
58

59
60
61
62
63
64
65
66







-
+






-
+

-
+

-
+








    /*
     * 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
    int 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
    int selectFirst;		/* Character index of first selected character
				 * (-1 means nothing selected. */
    TkSizeT selectLast;		/* Character index just after last selected
    int selectLast;		/* Character index just after last selected
				 * character (-1 means nothing selected. */
    TkSizeT selectAnchor;		/* Fixed end of selection (i.e. "select to"
    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
124
125
126
127
128
129
130













131
132
133
134
135
136
137
138
139
140


141
142
143
144
145
146

147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163







-
-
-
-
-
-
-
-
-
-
-
-
-










-
-
+
+




-
+








-
+







				 * 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
    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. */
    TkSizeT numDisplayBytes;	/* Length of displayString in bytes. */
    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). */
    TkSizeT leftIndex;		/* Character index of left-most character
    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. */
226
227
228
229
230
231
232
233

234
235

236
237

238
239
240
241
242
243
244
213
214
215
216
217
218
219

220
221

222
223

224
225
226
227
228
229
230
231







-
+

-
+

-
+







    double fromValue;		/* Value corresponding to left/top of dial */
    double toValue;		/* Value corresponding to right/bottom of
				 * dial */
    double increment;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    char *formatBuf;		/* string into which to format value.
				 * Malloc'ed. */
    char *reqFormat;		/* Sprintf conversion specifier used for the
    char *reqFormat;		/* Snprintf conversion specifier used for the
				 * value that the users requests. Malloc'ed */
    char *valueFormat;		/* Sprintf conversion specifier used for the
    char *valueFormat;		/* Snprintf conversion specifier used for the
				 * value. */
    char digitFormat[16];	/* Sprintf conversion specifier computed from
    char digitFormat[16];	/* Snprintf conversion specifier computed from
				 * digits and other information; used for the
				 * value. */

    char *valueStr;		/* Values List. Malloc'ed. */
    Tcl_Obj *listObj;		/* Pointer to the list object being used */
    int eIndex;			/* Holds the current index into elements */
    int nElements;		/* Holds the current count of elements */
Changes to generic/tkError.c.
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90







-
+







				 * codes). */
    int minorCode,		/* Consider only errors with this minor
				 * request code (-1 means consider all minor
				 * codes). */
    Tk_ErrorProc *errorProc,	/* Procedure to invoke when a matching error
				 * occurs. NULL means just ignore matching
				 * errors. */
    ClientData clientData)	/* Arbitrary value to pass to errorProc. */
    void *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.
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120







-
+







    /*
     * Create the handler record.
     */

    errorPtr = (TkErrorHandler *)ckalloc(sizeof(TkErrorHandler));
    errorPtr->dispPtr = dispPtr;
    errorPtr->firstRequest = NextRequest(display);
    errorPtr->lastRequest = (unsigned) -1;
    errorPtr->lastRequest = (unsigned long) -1;
    errorPtr->error = error;
    errorPtr->request = request;
    errorPtr->minorCode = minorCode;
    errorPtr->errorProc = errorProc;
    errorPtr->clientData = clientData;
    errorPtr->nextPtr = dispPtr->errorPtr;
    dispPtr->errorPtr = errorPtr;
148
149
150
151
152
153
154





155
156
157
158
159
160
161
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166







+
+
+
+
+







				 * return value from Tk_CreateErrorHandler. */
{
    TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
    TkDisplay *dispPtr = errorPtr->dispPtr;

    errorPtr->lastRequest = NextRequest(dispPtr->display) - 1;

    /*
     * Ensure that no user callback for this handler is invoked any further.
     */
    errorPtr->errorProc = NULL;

    /*
     * 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
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
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 "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.
209
210
211
212
213
214
215

216

217
218
219
220
221
222
223
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217







+

+







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);
#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
317
318
319
320
321
322
323

324
325
326
327
328
329
330
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325







+







 *
 *	Create the X input context for our winPtr.
 *	XIM is only ever enabled on Unix.
 *
 *----------------------------------------------------------------------
 */

#ifdef TK_USE_INPUT_METHODS
static void
CreateXIC(
    TkWindow *winPtr)
{
    TkDisplay *dispPtr = winPtr->dispPtr;
    long im_event_mask = 0L;
    const char *preedit_attname = NULL;
363
364
365
366
367
368
369

370
371
372
373
374
375
376
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372







+







     */
    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
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







-
+

-
+
-
-
-











-
+
-



-
+


-
+







    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetButtonMask --
 * TkGetButtonMask --
 *
 *	Return the proper Button${n}Mask for the button. Don't care about
 *	Return the proper Button${n}Mask for the button.
 *	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, \
    0, Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask
	    Button5Mask, Button6Mask, Button7Mask, Button8Mask, Button9Mask
};

unsigned
Tk_GetButtonMask(
TkGetButtonMask(
    unsigned button)
{
    return (button > Button9) ? 0 : buttonMasks[button];
    return (button > Button5) ? 0 : buttonMasks[button];
}

/*
 *----------------------------------------------------------------------
 *
 * InvokeClientMessageHandlers --
 *
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
980
981
982
983
984
985
986


































987
988
989
990
991
992
993







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkEventInit --
 *
 *	This functions initializes all the event module structures used by the
 *	current thread. It must be called before any other function in this
 *	file is called.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkEventInit(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->handlersActive	= 0;
    tsdPtr->pendingPtr		= NULL;
    tsdPtr->genericList		= NULL;
    tsdPtr->lastGenericPtr	= NULL;
    tsdPtr->cmList		= NULL;
    tsdPtr->lastCmPtr		= NULL;
    tsdPtr->restrictProc	= NULL;
    tsdPtr->restrictArg		= NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkXErrorHandler --
 *
 *	TkXErrorHandler is an error handler, to be installed via
 *	Tk_CreateErrorHandler, that will set a flag if an X error occurred.
 *
 * Results:
 *	Always returns 0, indicating that the X error was handled.
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
1094
1095
1096
1097
1098
1099
1100


1101





1102
1103


1104



1105


1106
1107
1108
1109
1110
1111
1112







-
-
+
-
-
-
-
-
+
+
-
-
+
-
-
-
+
-
-







    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 !defined(MAC_OSX_TK) && !defined(_WIN32)
    if ((eventPtr->xbutton.button >= Button4) && (eventPtr->xbutton.button < Button8)) {
	if (eventPtr->type == ButtonRelease) {
	    return;
	} else if (eventPtr->type == ButtonPress) {
	    int but = eventPtr->xbutton.button;
    if (((eventPtr->type == ButtonPress) || (eventPtr->type == ButtonRelease))
	    && ((eventPtr->xbutton.button - 6) < 2)) {
	    eventPtr->type = MouseWheelEvent;
	    eventPtr->xany.send_event = -1;
	eventPtr->xbutton.button -= 2;
	    eventPtr->xkey.keycode = (but & 1) ? -120 : 120;
	    if (but > Button5) {
		eventPtr->xkey.state ^= ShiftMask;
	eventPtr->xbutton.state ^= ShiftMask;
	    }
	}
    }
#endif

    /*
     * If the generic handler processed this event we are done and can return.
     */

1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231
1232
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182







+







    /*
     * 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 the XIC has been invalidated, it must be recreated.
     */
    if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) {
	winPtr->flags &= ~TK_CHECKED_IC;
	winPtr->inputContext = NULL;
    }
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204







+







	}
	if ((eventPtr->type == FocusIn) &&
		(winPtr->dispPtr->inputMethod != NULL) &&
		(winPtr->inputContext != NULL)) {
	    XSetICFocus(winPtr->inputContext);
	}
    }
#endif /*TK_USE_INPUT_METHODS*/

    /*
     * For events where it hasn't already been done, update the current time
     * in the display.
     */

    if (eventPtr->type == PropertyNotify) {
2003
2004
2005
2006
2007
2008
2009
2010

2011
2012
2013
2014
2015
2016
2017
1954
1955
1956
1957
1958
1959
1960

1961
1962
1963
1964
1965
1966
1967
1968







-
+








/*
 *----------------------------------------------------------------------
 *
 * TkFinalize --
 *
 *	Runs our private exit handlers and removes itself from Tcl. This is
 *	benificial should we want to protect from dangling pointers should the
 *	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.
Changes to generic/tkFileFilter.c.
258
259
260
261
262
263
264
265
266


267
268
269
270
271
272
273
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);
	    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).
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326



327
328
329
330
331
332
333
334

335
336
337
338
339

340
341
342
343
344
345
346
347
348

349
350
351

352
353
354
355

356
357
358
359
360
361
362
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323



324
325
326
327
328
329
330
331
332
333

334
335
336
337
338

339
340
341
342
343
344
345
346
347

348
349
350

351
352
353
354

355
356
357
358
359
360
361
362







-
+















-
-
-
+
+
+







-
+




-
+








-
+


-
+



-
+







	}
    }

    /*
     * Add the clause into the list of clauses
     */

    clausePtr = (FileFilterClause *)ckalloc(sizeof(FileFilterClause));
    clausePtr = 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);
	    GlobPattern *globPtr = 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(len + 1);
		globPtr->pattern = ckalloc(len + 1);
		globPtr->pattern[0] = '*';
		strcpy(globPtr->pattern+1, str);
	    } else if (isWindows) {
		if (strcmp(str, "*") == 0) {
		    globPtr->pattern = (char *)ckalloc(4);
		    globPtr->pattern = 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);
		    globPtr->pattern = ckalloc(3);
		    strcpy(globPtr->pattern, "*.");
		} else {
		    globPtr->pattern = (char *)ckalloc(len);
		    globPtr->pattern = ckalloc(len);
		    strcpy(globPtr->pattern, str);
		}
	    } else {
		globPtr->pattern = (char *)ckalloc(len);
		globPtr->pattern = ckalloc(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
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);
	    int len;
	    MacFileType *mfPtr = 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
	     */

441
442
443
444
445
446
447
448

449
450
451
452

453
454
455
456
457
458
459
441
442
443
444
445
446
447

448
449
450
451

452
453
454
455
456
457
458
459







-
+



-
+








    for (; filterPtr; filterPtr=filterPtr->next) {
	if (strcmp(filterPtr->name, name) == 0) {
	    return filterPtr;
	}
    }

    filterPtr = (FileFilter *)ckalloc(sizeof(FileFilter));
    filterPtr = ckalloc(sizeof(FileFilter));
    filterPtr->clauses = NULL;
    filterPtr->clausesTail = NULL;
    len = strlen(name) + 1;
    filterPtr->name = (char *)ckalloc(len);
    filterPtr->name = ckalloc(len);
    memcpy(filterPtr->name, name, len);

    if (flistPtr->filters == NULL) {
	flistPtr->filters = flistPtr->filtersTail = filterPtr;
    } else {
	flistPtr->filtersTail->next = filterPtr;
	flistPtr->filtersTail = filterPtr;
Changes to generic/tkFileFilter.h.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 _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 "*.*" */
75
76
77
78
79
80
81
82
83
84
85
86
71
72
73
74
75
76
77




78







-
-
-
-


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 */
Changes to generic/tkFocus.c.
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+








/*
 * Debugging support...
 */

#define DEBUG(dispPtr, arguments) \
    if ((dispPtr)->focusDebug) { \
	printf arguments; \
	printf arguments; fflush(stdout); \
    }

/*
 * Forward declarations for functions defined in this file:
 */

static DisplayFocusInfo*FindDisplayFocusInfo(TkMainInfo *mainPtr,
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138







-
+







     * 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));
	    Tcl_SetObjResult(interp, TkNewWindowObj(focusWin));
	}
	return TCL_OK;
    }

    /*
     * If invoked with a single argument beginning with "." then focus on that
     * window.
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189







-
+







	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));
	    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) newPtr));
	}
	break;
    case 1:			/* -force */
	windowName = Tcl_GetString(objv[2]);

	/*
	 * The empty string case exists for backwards compatibility.
208
209
210
211
212
213
214
215

216
217
218
219
220

221
222
223
224
225
226
227
208
209
210
211
212
213
214

215
216
217
218
219

220
221
222
223
224
225
226
227







-
+




-
+







		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)
		    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window)
			    tlFocusPtr->focusWinPtr));
		    return TCL_OK;
		}
	    }
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) topLevelPtr));
	    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) topLevelPtr));
	    return TCL_OK;
	}
	break;
    default:
	Tcl_Panic("bad const entries to focusOptions in focus command");
    }
    return TCL_OK;
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325







-
+







	 * Skip FocusIn events that cause confusion
	 * NotifyVirtual and NotifyNonlinearVirtual - Virtual events occur on
	 *	windows in between the origin and destination of the focus
	 *	change. For FocusIn we may see this when focus goes into an
	 *	embedded child. We don't care about this, although we may end
	 *	up getting a NotifyPointer later.
	 * NotifyInferior - focus is coming to us from an embedded child. When
	 *	focus is on an embeded focus, we still think we have the
	 *	focus is on an embedded focus, we still think we have the
	 *	focus, too, so this message doesn't change our state.
	 * NotifyPointerRoot - should never happen because this is sent to the
	 *	root window.
	 *
	 * Interesting FocusIn events are
	 * NotifyAncestor - focus is coming from our parent, probably the root.
	 * NotifyNonlinear - focus is coming from a different branch, probably
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379







-
+







	retValue = 1;
	if (eventPtr->xcrossing.detail == NotifyInferior) {
	    return retValue;
	}
    }

    /*
     * If winPtr isn't a top-level window than just ignore the event.
     * If winPtr isn't a top-level window then just ignore the event.
     */

    winPtr = TkWmFocusToplevel(winPtr);
    if (winPtr == NULL) {
	return retValue;
    }

497
498
499
500
501
502
503
504

505
506
507
508
509

510
511
512
513
514
515
516
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
517







-
+





+







	 * 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"));
	    DEBUG(dispPtr, ("Defocussed implicit Async from %s\n", displayFocusPtr->focusWinPtr->pathName));
	    GenerateFocusEvents(displayFocusPtr->focusWinPtr, NULL);
	    XSetInputFocus(dispPtr->display, PointerRoot, RevertToPointerRoot,
		    CurrentTime);
	    displayFocusPtr->focusWinPtr = NULL;
	    dispPtr->implicitWinPtr = NULL;
	    dispPtr->focusPtr = NULL;
	}
    }
    return retValue;
}

/*
 *----------------------------------------------------------------------
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
633
634
635
636
637
638
639

640
641
642
643
644
645
646
647







-
+







    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.
	 * container.
	 */

	TkpClaimFocus(topLevelPtr, force);
    } else if ((displayFocusPtr->focusWinPtr != NULL) || force) {

	/*
	 * If we are forcing removal of focus from a container hosting a
809
810
811
812
813
814
815

816
817
818
819
820
821
822
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824







+







TkFocusDeadWindow(
    TkWindow *winPtr)	/* Information about the window that is being
				 * deleted. */
{
    ToplevelFocusInfo *tlFocusPtr, *prevPtr;
    DisplayFocusInfo *displayFocusPtr;
    TkDisplay *dispPtr = winPtr->dispPtr;
    int noMatch = 1;

    /*
     * Certain special windows like those used for send and clipboard have no
     * mainPtr.
     */

    if (winPtr->mainPtr == NULL) {
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
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







+

















+

















+
+
+
+
+
+
+
+
+







	    }
	    if (prevPtr == NULL) {
		winPtr->mainPtr->tlFocusPtr = tlFocusPtr->nextPtr;
	    } else {
		prevPtr->nextPtr = tlFocusPtr->nextPtr;
	    }
	    ckfree(tlFocusPtr);
	    noMatch = 0;
	    break;
	} else if (winPtr == tlFocusPtr->focusWinPtr) {
	    /*
	     * The deleted window had the focus for its top-level: move the
	     * focus to the top-level itself.
	     */

	    tlFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
	    if ((displayFocusPtr->focusWinPtr == winPtr)
		    && !(tlFocusPtr->topLevelPtr->flags & TK_ALREADY_DEAD)) {
		DEBUG(dispPtr, ("forwarding focus to %s after %s died\n",
			tlFocusPtr->topLevelPtr->pathName, winPtr->pathName));
		GenerateFocusEvents(displayFocusPtr->focusWinPtr,
			tlFocusPtr->topLevelPtr);
		displayFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr;
		dispPtr->focusPtr = tlFocusPtr->topLevelPtr;
	    }
	    noMatch = 0;
	    break;
	}
    }

    /*
     * Occasionally, things can become unsynchronized. Move them back into
     * synch now. [Bug 2496114]
     */

    if (displayFocusPtr->focusWinPtr == winPtr) {
	DEBUG(dispPtr, ("focus cleared after %s died\n", winPtr->pathName));
	displayFocusPtr->focusWinPtr = NULL;
    }

    if (displayFocusPtr->focusOnMapPtr == winPtr) {
	displayFocusPtr->focusOnMapPtr = NULL;
    }

    /*
     * It may happen that the search above for focus records that refer
     * to this window did not find any match. In such a case, when the
     * dead window had the focus, release it.
     */
    if (noMatch && (dispPtr->focusPtr == winPtr)) {
	dispPtr->focusPtr = NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateFocusEvents --
 *
1033
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1046
1047
1048
1049
1050
1051
1052

1053
1054
1055
1056
1057
1058
1059
1060







-
+







 *
 *	Free resources associated with maintaining the focus.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	This mainPtr should no long access focus information.
 *	This mainPtr should no longer access focus information.
 *
 *----------------------------------------------------------------------
 */

void
TkFocusFree(
    TkMainInfo *mainPtr)	/* Record that identifies a particular
1163
1164
1165
1166
1167
1168
1169
1170

1171
1172
1173
1174
1175
1176
1177
1176
1177
1178
1179
1180
1181
1182

1183
1184
1185
1186
1187
1188
1189
1190







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkFocusJoin --
 *
 *	Remove the focus record for this window that is nolonger managed
 *	Remove the focus record for this window that is no longer managed
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A tlFocusPtr record is removed
 *
Changes to generic/tkFont.c.
13
14
15
16
17
18
19




20
21
22
23
24
25
26
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30







+
+
+
+








#include "tkInt.h"
#include "tkFont.h"
#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"    /* Defines TK_DRAW_IN_CONTEXT */
#endif

#ifdef _WIN32
#include "tkWinInt.h"
#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.
 */

typedef struct TkFontInfo {
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58







-
+







/*
 * 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 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
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368







-
+







 */

const Tcl_ObjType tkFontObjType = {
    "font",			/* name */
    FreeFontObjProc,		/* freeIntRepProc */
    DupFontObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
    SetFontFromAny		/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * TkFontPkgInit --
 *
412
413
414
415
416
417
418

419

420
421
422
423

424

425
426
427
428
429
430
431
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439







+

+




+

+







void
TkFontPkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
{
    TkFontInfo *fiPtr = mainPtr->fontInfoPtr;
    Tcl_HashEntry *hPtr, *searchPtr;
    Tcl_HashSearch search;
#ifdef PURIFY
    int fontsLeft = 0;
#endif

    for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
	    searchPtr != NULL;
	    searchPtr = Tcl_NextHashEntry(&search)) {
#ifdef PURIFY
	fontsLeft++;
#endif
#ifdef DEBUG_FONTS
	fprintf(stderr, "Font %s still in cache.\n",
		(char *) Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
    }

#ifdef PURIFY
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
522
523
524
525
526
527
528

529
530
531
532
533
534
535
536







-
+







	    return TCL_ERROR;
	}

	/*
	 * Next parameter may be an option.
	 */

	n = skip + 3;
	n = 3 + skip;
	optPtr = NULL;
	charPtr = NULL;
	if (n < objc) {
	    s = Tcl_GetString(objv[n]);
	    if (s[0] == '-' && s[1] != '-') {
		optPtr = objv[n];
		n++;
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
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 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?");
		    "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);
	    int len = TkUtfToUniChar(string, &uniChar);

	    if (len != (size_t)charPtr->length) {
	    if (len != 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);
656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
664
665
666
667
668
669
670

671
672
673
674
675
676
677
678







-
+







	}
	if (name == NULL) {
	    /*
	     * No font name specified. Generate one of the form "fontX".
	     */

	    for (i = 1; ; i++) {
		sprintf(buf, "font%d", i);
		snprintf(buf, sizeof(buf), "font%d", i);
		namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf);
		if (namedHashPtr == NULL) {
		    break;
		}
	    }
	    name = buf;
	    skip = 2;
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
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







-
+









-
+








-
+








-
-
+
+
















-
+

-
+







    }
    case FONT_FAMILIES: {
	int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);

	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 2) {
	if (objc != 2 + skip) {
	    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 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) {
	if (objc != 4 + skip) {
	    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(
	string = Tcl_GetStringFromObj(objv[3 + skip], &length);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(
		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)) {
	if ((objc < 3) || (objc > 4 + skip)) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? ?-option?");
		    "font ?-displayof window? ?option?");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;
	}
	objc -= skip;
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
785
786
787
788
789
790
791

792
793
794
795
796
797
798
799







-
+







	    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));
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(i));
	}
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *namedHashPtr;
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
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







+










-
+




-
-
-
-
+
+
+
+





-
-
+
+

+
+
+
+
+
+
+








static void
RecomputeWidgets(
    TkWindow *winPtr)		/* Window to which command is sent. */
{
    Tk_ClassWorldChangedProc *proc =
	    Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc);
    TkWindow *tkwinPtr;

    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
     * option will be leaf nodes in the widget heirarchy (buttons, labels,
     * option will be leaf nodes in the widget hierarchy (buttons, labels,
     * etc.), so the recursion depth will be shallow.
     *
     * However, the additional overhead of the recursive calls may become a
     * performance problem if typical usage alters such that -font'ed widgets
     * appear high in the heirarchy, causing deep recursion. This could happen
     * with text widgets, or more likely with the (not yet existant) labeled
     * frame widget. With these widgets it is possible, even likely, that a
     * -font'ed widget (text or labeled frame) will not be a leaf node, but
     * appear high in the hierarchy, causing deep recursion. This could happen
     * with text widgets, or more likely with the labelframe
     * widget. With these widgets it is possible, even likely, that a
     * -font'ed widget (text or labelframe) will not be a leaf node, but
     * will instead have many descendants. If this is ever found to cause a
     * performance problem, it may be worth investigating an iterative version
     * of the code below.
     */

    for (winPtr=winPtr->childList ; winPtr!=NULL ; winPtr=winPtr->nextPtr) {
	RecomputeWidgets(winPtr);
    for (tkwinPtr=winPtr->childList ; tkwinPtr!=NULL ; tkwinPtr=tkwinPtr->nextPtr) {
	RecomputeWidgets(tkwinPtr);
    }

    /*
     * Broadcast font change virtually for mega-widget layout managers.
     * Do this after the font change has been propagated to core widgets.
    */
    TkSendVirtualEvent((Tk_Window)winPtr, "TkWorldChanged",
		       Tcl_NewStringObj("FontChanged",-1));
}

/*
 *---------------------------------------------------------------------------
 *
 * TkCreateNamedFont --
 *
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732
1733
1734








1735
1736
1737
1738
1739
1740
1741
1739
1740
1741
1742
1743
1744
1745
1746





1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761







+
-
-
-
-
-
+
+
+
+
+
+
+
+







	upper = 1;
	for (; *src != '\0'; ) {
	    while (isspace(UCHAR(*src))) { /* INTL: ISO space */
		src++;
		upper = 1;
	    }
	    src += TkUtfToUniChar(src, &ch);
	    if (ch <= 0xffff) {
	    if (upper) {
		ch = Tcl_UniCharToUpper(ch);
		upper = 0;
	    } else {
		ch = Tcl_UniCharToLower(ch);
		if (upper) {
		    ch = Tcl_UniCharToUpper(ch);
		    upper = 0;
		} else {
		    ch = Tcl_UniCharToLower(ch);
		}
	    } else {
		upper = 0;
	    }
	    dest += TkUniCharToUtf(ch, dest);
	}
	*dest = '\0';
	Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr));
	family = Tcl_DStringValue(dsPtr) + len;
    }
1965
1966
1967
1968
1969
1970
1971

1972

1973
1974
1975
1976
1977
1978
1979
1985
1986
1987
1988
1989
1990
1991
1992

1993
1994
1995
1996
1997
1998
1999
2000







+
-
+







				 * 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;
    int n, y, bytesThisChunk, maxChunks, curLine, layoutHeight;
    int 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);
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
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







-
+














-
+







    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;

    layoutPtr = (TextLayout *)ckalloc(offsetof(TextLayout, chunks)
    layoutPtr = (TextLayout *)ckalloc(Tk_Offset(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);
    endp = TkUtfAtIndex(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) {
	    /*
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
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







+
-
+



















-
+






-
+







				 * 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, drawX;
    int i, numDisplayChars, drawX;
    int numDisplayChars;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;

    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)) {
	    if (firstChar <= 0) {
		drawX = 0;
		firstChar = 0;
		firstByte = chunkPtr->start;
	    } else {
		firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar);
		firstByte = TkUtfAtIndex(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);
	    lastByte = TkUtfAtIndex(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,
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







-
+






-
+







	    double dx, dy;

	    if (firstChar <= 0) {
		drawX = 0;
		firstChar = 0;
		firstByte = chunkPtr->start;
	    } else {
		firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar);
		firstByte = TkUtfAtIndex(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);
	    lastByte = TkUtfAtIndex(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,
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
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







-
+









+











-
+







				 * 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;
    LayoutChunk *chunkPtr;
    int i, x = 0, w;
    Tk_Font tkfont;
    TkFont *fontPtr;
    const char *end;

    if (index < 0) {
	return 0;
    }

    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);
	    end = TkUtfAtIndex(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;
3282
3283
3284
3285
3286
3287
3288
3289

3290
3291
3292
3293
3294
3295
3296
3305
3306
3307
3308
3309
3310
3311

3312
3313
3314
3315
3316
3317
3318
3319







-
+







    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;
    int 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) {
3311
3312
3313
3314
3315
3316
3317
3318

3319
3320
3321
3322
3323
3324
3325
3334
3335
3336
3337
3338
3339
3340

3341
3342
3343
3344
3345
3346
3347
3348







-
+







	     * 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,
		 * Tricky point: the "03" is necessary in the snprintf 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;
3337
3338
3339
3340
3341
3342
3343
3344

3345
3346
3347

3348
3349
3350
3351
3352
3353
3354
3360
3361
3362
3363
3364
3365
3366

3367
3368
3369

3370
3371
3372
3373
3374
3375
3376
3377







-
+


-
+







	     * 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? */
	    snprintf(uindex, sizeof(uindex), "%04X", ch);		/* endianness? */
	    glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0);
	    if (glyphname) {
		ps = TkGetStringFromObj(psObj, &len);
		ps = Tcl_GetStringFromObj(psObj, &len);
		if (ps[len-1] == '(') {
		    /*
		     * In-place edit. Ewww!
		     */

		    ps[len-1] = '/';
		} else {
3402
3403
3404
3405
3406
3407
3408

3409

3410
3411
3412
3413
3414
3415
3416
3425
3426
3427
3428
3429
3430
3431
3432

3433
3434
3435
3436
3437
3438
3439
3440







+
-
+







    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;
    int i, n, index;
    int 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,
3531
3532
3533
3534
3535
3536
3537
3538

3539
3540

3541
3542
3543
3544
3545
3546
3547
3555
3556
3557
3558
3559
3560
3561

3562
3563

3564
3565
3566
3567
3568
3569
3570
3571







-
+

-
+







	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));
		valuePtr = Tcl_NewIntObj((int)(faPtr->size + 0.5));
	    } else {
		valuePtr = Tcl_NewWideIntObj(-(Tcl_WideInt)(-faPtr->size + 0.5));
		valuePtr = Tcl_NewIntObj(-(int)(-faPtr->size + 0.5));
	    }
	    break;

	case FONT_WEIGHT:
	    str = TkFindStateString(weightMap, faPtr->weight);
	    valuePtr = Tcl_NewStringObj(str, -1);
	    break;
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
3590
3591
3592
3593
3594
3595
3596



















































3597
3598
3599
3600
3601
3602
3603







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	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
3654
3655
3656
3657
3658
3659
3660

3661

3662
3663
3664
3665
3666
3667
3668
3627
3628
3629
3630
3631
3632
3633
3634

3635
3636
3637
3638
3639
3640
3641
3642







+
-
+







    Tcl_Obj *objPtr,		/* Parseable font description object. */
    TkFontAttributes *faPtr)	/* Filled with attributes parsed from font
				 * name. Any attributes that were not
				 * specified in font name are filled with
				 * default values. */
{
    const char *dash;
    int result, n;
    int objc, result, i, n;
    int objc, i;
    Tcl_Obj **objv;
    const char *string;

    TkInitFontAttributes(faPtr);

    string = Tcl_GetString(objPtr);
    if (*string == '-') {
3821
3822
3823
3824
3825
3826
3827
3828

3829
3830
3831
3832
3833
3834
3835
3795
3796
3797
3798
3799
3800
3801

3802
3803
3804
3805
3806
3807
3808
3809







-
+







    int maxChunks, numChars;
    size_t s;

    layoutPtr = *layoutPtrPtr;
    maxChunks = *maxPtr;
    if (layoutPtr->numChunks == maxChunks) {
	maxChunks *= 2;
	s = offsetof(TextLayout, chunks) + (maxChunks * sizeof(LayoutChunk));
	s = Tk_Offset(TextLayout, chunks) + (maxChunks * sizeof(LayoutChunk));
	layoutPtr = (TextLayout *)ckrealloc(layoutPtr, s);

	*layoutPtrPtr = layoutPtr;
	*maxPtr = maxChunks;
    }
    numChars = Tcl_NumUtfChars(start, numBytes);
    chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks];
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
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







-
+
















-
+

-
+







 *----------------------------------------------------------------------
 */

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. */
    const char *name)		/* Name of the desired font. */
{
    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_NewIntObj(fontPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(fontPtr->objRefCount));
		    Tcl_NewIntObj(fontPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
Changes to generic/tkFont.h.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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.
 */

#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 {
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+









-
+







 */

typedef struct TkFont {
    /*
     * Fields used and maintained exclusively by generic code.
     */

    TkSizeT resourceRefCount;	/* Number of active uses of this font (each
    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. */
    TkSizeT objRefCount;		/* The number of Tcl objects that reference
    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. */
221
222
223
224
225
226
227
228
229
230
231
232
217
218
219
220
221
222
223




224







-
-
-
-

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 */
Changes to generic/tkFrame.c.
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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. */
    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:
 */

180
181
182
183
184
185
186
187

188
189
190

191
192

193
194
195
196
197
198
199

200
201

202
203
204

205
206
207


208
209

210
211
212
213


214
215
216


217
218
219


220
221

222
223
224

225
226
227

228
229
230
231
232
233
234
235
236

237
238
239
240

241
242

243
244

245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260

261
262

263
264

265
266
267

268
269

270
271
272
273
274

275
276
277
278
279
280
281
282

283
284

285
286
287

288
289

290
291

292
293

294
295

296
297
298

299
300

301
302

303
304
305
306
307
308
309
170
171
172
173
174
175
176

177
178
179

180
181

182
183
184
185
186
187
188

189
190

191
192
193

194
195


196
197
198

199
200
201


202
203
204


205
206
207


208
209
210

211
212
213

214
215
216

217
218
219
220
221



222

223


224

225
226

227
228

229


230
231
232
233
234



235

236


237

238
239

240
241

242
243
244

245
246

247
248


249

250
251
252
253
254
255
256
257

258
259

260
261
262

263
264

265
266

267
268

269
270

271
272
273

274
275

276
277

278
279
280
281
282
283
284
285







-
+


-
+

-
+






-
+

-
+


-
+

-
-
+
+

-
+


-
-
+
+

-
-
+
+

-
-
+
+

-
+


-
+


-
+




-
-
-

-
+
-
-

-
+

-
+

-
+
-
-





-
-
-

-
+
-
-

-
+

-
+

-
+


-
+

-
+

-
-

-
+







-
+

-
+


-
+

-
+

-
+

-
+

-
+


-
+

-
+

-
+







/*
 * 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),
	DEF_FRAME_BG_COLOR, -1, Tk_Offset(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},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_STRING, "-colormap", "colormap", "Colormap",
	DEF_FRAME_COLORMAP, TCL_INDEX_NONE, offsetof(Frame, colormapName),
	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, TCL_INDEX_NONE, offsetof(Frame, isContainer), 0, 0, 0},
	DEF_FRAME_CONTAINER, -1, Tk_Offset(Frame, isContainer), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_FRAME_CURSOR, TCL_INDEX_NONE, offsetof(Frame, cursor),
	DEF_FRAME_CURSOR, -1, Tk_Offset(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},
	DEF_FRAME_HEIGHT, -1, Tk_Offset(Frame, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, TCL_INDEX_NONE,
	offsetof(Frame, highlightBgColorPtr), 0, 0, 0},
	"HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, -1,
	Tk_Offset(Frame, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_FRAME_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Frame, highlightColorPtr),
	DEF_FRAME_HIGHLIGHT, -1, Tk_Offset(Frame, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Frame, highlightWidth), 0, 0, 0},
	"HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Frame, highlightWidth), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_FRAME_PADX, offsetof(Frame, padXPtr),
	offsetof(Frame, padX), 0, 0, 0},
	DEF_FRAME_PADX, Tk_Offset(Frame, padXPtr),
	Tk_Offset(Frame, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_FRAME_PADY, offsetof(Frame, padYPtr),
	offsetof(Frame, padY), 0, 0, 0},
	DEF_FRAME_PADY, Tk_Offset(Frame, padYPtr),
	Tk_Offset(Frame, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_FRAME_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Frame, 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, TCL_INDEX_NONE, offsetof(Frame, visualName),
	DEF_FRAME_VISUAL, -1, Tk_Offset(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},
	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_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},
	NULL, 0, -1, 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},
	DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_FRAME_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
	DEF_FRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_FRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
	DEF_FRAME_RELIEF, -1, Tk_Offset(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},
	NULL, 0, -1, 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},
	DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_TOPLEVEL_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
	DEF_TOPLEVEL_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_TOPLEVEL_MENU, TCL_INDEX_NONE, offsetof(Frame, menuName),
	DEF_TOPLEVEL_MENU, -1, Tk_Offset(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},
	DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-screen", "screen", "Screen",
	DEF_TOPLEVEL_SCREEN, TCL_INDEX_NONE, offsetof(Frame, screenName),
	DEF_TOPLEVEL_SCREEN, -1, Tk_Offset(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),
	DEF_TOPLEVEL_USE, -1, Tk_Offset(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},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_LABELFRAME_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Frame, borderWidth),
	DEF_LABELFRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth),
	0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_LABELFRAME_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
	DEF_LABELFRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_LABELFRAME_FONT, TCL_INDEX_NONE, offsetof(Labelframe, tkfont), 0, 0, 0},
	DEF_LABELFRAME_FONT, -1, Tk_Offset(Labelframe, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_LABELFRAME_FG, TCL_INDEX_NONE, offsetof(Labelframe, textColorPtr), 0, 0, 0},
	DEF_LABELFRAME_FG, -1, Tk_Offset(Labelframe, textColorPtr), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor",
	DEF_LABELFRAME_LABELANCHOR, TCL_INDEX_NONE, offsetof(Labelframe, labelAnchor),
	DEF_LABELFRAME_LABELANCHOR, -1, Tk_Offset(Labelframe, labelAnchor),
	0, labelAnchorStrings, 0},
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget",
	NULL, TCL_INDEX_NONE, offsetof(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABELFRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
	DEF_LABELFRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_LABELFRAME_TEXT, offsetof(Labelframe, textPtr), TCL_INDEX_NONE,
	DEF_LABELFRAME_TEXT, Tk_Offset(Labelframe, textPtr), -1,
	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.
325
326
327
328
329
330
331
332
333


334
335

336
337

338
339
340
341
342
343
344
345


346
347

348
349

350
351

352
353

354
355
356
357


358
359
360
361
362
363
364
301
302
303
304
305
306
307


308
309
310

311
312

313








314
315
316

317
318

319
320

321
322

323
324
325


326
327
328
329
330
331
332
333
334







-
-
+
+

-
+

-
+
-
-
-
-
-
-
-
-
+
+

-
+

-
+

-
+

-
+


-
-
+
+







/*
 * 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[],
static int		CreateFrame(void *clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[],
			    enum FrameType type, const char *appName);
static void		DestroyFrame(void *memPtr);
static Tcl_FreeProc	DestroyFrame;
static void		DestroyFramePartly(Frame *framePtr);
static void		DisplayFrame(ClientData clientData);
static void		DisplayFrame(void *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,
static void		FrameCmdDeletedProc(void *clientData);
static void		FrameEventProc(void *clientData,
			    XEvent *eventPtr);
static void		FrameLostContentProc(ClientData clientData,
static void		FrameLostContentProc(void *clientData,
			    Tk_Window tkwin);
static void		FrameRequestProc(ClientData clientData,
static void		FrameRequestProc(void *clientData,
			    Tk_Window tkwin);
static void		FrameStructureProc(ClientData clientData,
static void		FrameStructureProc(void *clientData,
			    XEvent *eventPtr);
static int		FrameWidgetObjCmd(ClientData clientData,
static int		FrameWidgetObjCmd(void *clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		FrameWorldChanged(ClientData instanceData);
static void		MapFrame(ClientData clientData);
static void		FrameWorldChanged(void *instanceData);
static void		MapFrame(void *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 = {
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400







-
+









-
+









-
+







 *	call CreateFrame to do all of the real work.
 *
 *--------------------------------------------------------------
 */

int
Tk_FrameObjCmd(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    void *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. */
    void *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. */
    void *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);
}

445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
415
416
417
418
419
420
421

422
423
424
425
426
427
428
429







-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkCreateFrame(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    void *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.
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
445
446
447
448
449
450
451

452
453
454
455
456
457
458
459







-
+







    }
    ckfree(objv);
    return result;
}

int
TkListCreateFrame(
    ClientData clientData,	/* Either NULL or pointer to option table. */
    void *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
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
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







-
+
















-
+



-







    return CreateFrame(clientData, interp, objc, objv,
	    toplevel ? TYPE_TOPLEVEL : TYPE_FRAME,
	    nameObj ? Tcl_GetString(nameObj) : NULL);
}

static int
CreateFrame(
    ClientData dummy,	/* NULL. */
    TCL_UNUSED(void *),
    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;
    int length;
    unsigned int mask;
    Colormap colormap;
    Visual *visual;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526







-
+







     * 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);
	arg = Tcl_GetStringFromObj(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)
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
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







-
+

















-
+







    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)
    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) {
	    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));
    Tcl_SetObjResult(interp, TkNewWindowObj(newWin));
    return TCL_OK;

  error:
    if (newWin != NULL) {
	Tk_DestroyWindow(newWin);
    }
    return TCL_ERROR;
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
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







-
+













-
+


















-
+









-
+














-
+


















-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
FrameWidgetObjCmd(
    ClientData clientData,	/* Information about frame widget. */
    void *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;
    int 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,
	objPtr = Tk_GetOptionValue(interp, (char *) 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,
	    objPtr = Tk_GetOptionInfo(interp, (char *) 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);
		const char *arg = Tcl_GetStringFromObj(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
#ifdef _WIN32
		    if (c == 'u') {
			const char *string = Tcl_GetString(objv[i+1]);

			if (TkpUseWindow(interp, framePtr->tkwin,
				string) != TCL_OK) {
			    result = TCL_ERROR;
			    goto done;
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
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







-
+










-
-
-
-
-



-
-
-







 *	Everything associated with the frame is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyFrame(
    void *memPtr)		/* Info about frame widget. */
    char *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 --
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
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







-















-
+







-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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,
    if (Tk_SetOptions(interp, (char *) 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))
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
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







-
+
















-
-
-
-
-
-
-
-
-







 *	Frame will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
FrameWorldChanged(
    ClientData instanceData)	/* Information about widget. */
    void *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);
1471
1472
1473
1474
1475
1476
1477
1478

1479
1480
1481
1482
1483
1484

1485
1486
1487
1488
1489
1490
1491
1408
1409
1410
1411
1412
1413
1414

1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1428







-
+





-
+







 *	Commands are output to X to display the frame in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayFrame(
    ClientData clientData)	/* Information about widget. */
    void *clientData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)clientData;
    Tk_Window tkwin = framePtr->tkwin;
    int bdX1, bdY1, bdX2, bdY2, hlWidth;
    Pixmap pixmap;
    TkRegion clipRegion = NULL;
    Bool useClipping = False;

    framePtr->flags &= ~REDRAW_PENDING;
    if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    /*
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-







-
+

-
-
-
-








+
+
+
+
+
+
+
+
+
+
+
+
+
+







     * 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,
	TkpDrawFrame(tkwin, 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;
	}

#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);

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
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







-
-
-
-
+
+
-
+







-
+

-







	     * Draw label. If there is not room for the entire label, use
	     * clipping to get a nice appearance.
	     */

	    if ((labelframePtr->labelBox.width < labelframePtr->labelReqWidth)
		    || (labelframePtr->labelBox.height <
			    labelframePtr->labelReqHeight)) {
		clipRegion = TkCreateRegion();
		TkUnionRectWithRegion(&labelframePtr->labelBox, clipRegion,
			clipRegion);
		TkSetRegion(framePtr->display, labelframePtr->textGC,
		useClipping = True;
		XSetClipRectangles(framePtr->display, labelframePtr->textGC, 0, 0,
			clipRegion);
			&labelframePtr->labelBox, 1, Unsorted);
	    }

	    Tk_DrawTextLayout(framePtr->display, pixmap,
		    labelframePtr->textGC, labelframePtr->textLayout,
		    labelframePtr->labelTextX + LABELSPACING,
		    labelframePtr->labelTextY + LABELSPACING, 0, -1);

	    if (clipRegion != NULL) {
	    if (useClipping) {
		XSetClipMask(framePtr->display, labelframePtr->textGC, None);
		TkDestroyRegion(clipRegion);
	    }
	} else {
	    /*
	     * Reposition and map the window (but in different ways depending
	     * on whether the frame is the window's parent).
	     */

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
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







-
+
-

-
-
-
-
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	    } 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.
     */
	/*
	 * 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);
	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 */
}

    }

/*
 *----------------------------------------------------------------------
 *
 * 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 --
 *
1731
1732
1733
1734
1735
1736
1737
1738

1739
1740
1741
1742
1743
1744
1745
1629
1630
1631
1632
1633
1634
1635

1636
1637
1638
1639
1640
1641
1642
1643







-
+







 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
FrameEventProc(
    ClientData clientData,	/* Information about window. */
    void *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) {
1776
1777
1778
1779
1780
1781
1782
1783

1784
1785
1786
1787
1788
1789
1790
1674
1675
1676
1677
1678
1679
1680

1681
1682
1683
1684
1685
1686
1687
1688







-
+







	    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);
	Tcl_EventuallyFree(framePtr, DestroyFrame);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags |= GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
1824
1825
1826
1827
1828
1829
1830
1831

1832
1833
1834
1835
1836
1837
1838
1722
1723
1724
1725
1726
1727
1728

1729
1730
1731
1732
1733
1734
1735
1736







-
+







 *	The widget is destroyed.
 *
 *----------------------------------------------------------------------
 */

static void
FrameCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
    void *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);
1875
1876
1877
1878
1879
1880
1881
1882

1883
1884
1885
1886
1887
1888
1889
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
1787







-
+







 *	The frame given by the clientData argument is mapped.
 *
 *----------------------------------------------------------------------
 */

static void
MapFrame(
    ClientData clientData)		/* Pointer to frame structure. */
    void *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
1962
1963
1964
1965
1966
1967
1968
1969

1970
1971
1972
1973
1974
1975
1976
1860
1861
1862
1863
1864
1865
1866

1867
1868
1869
1870
1871
1872
1873
1874







-
+







 *	The window is disassociated from the frame when it is deleted.
 *
 *--------------------------------------------------------------
 */

static void
FrameStructureProc(
    ClientData clientData,	/* Pointer to record describing frame. */
    void *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
2000
2001
2002
2003
2004
2005
2006
2007
2008


2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
1898
1899
1900
1901
1902
1903
1904


1905
1906
1907
1908

1909
1910
1911
1912
1913
1914
1915







-
-
+
+


-







 *	on the options specified for the frame.
 *
 *--------------------------------------------------------------
 */

static void
FrameRequestProc(
    ClientData clientData,	/* Pointer to record for frame. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
    void *clientData,	/* Pointer to record for frame. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
{
    Frame *framePtr = (Frame *)clientData;
    (void)tkwin;

    FrameWorldChanged(framePtr);
}

/*
 *--------------------------------------------------------------
 *
2028
2029
2030
2031
2032
2033
2034
2035

2036
2037

2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
1925
1926
1927
1928
1929
1930
1931

1932
1933

1934
1935
1936
1937

1938
1939
1940
1941
1942
1943
1944







-
+

-
+



-







 *	Forgets all frame-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
FrameLostContentProc(
    ClientData clientData,	/* Frame structure for content window window that was
    void *clientData,	/* Frame structure for content window that was
				 * stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window window. */
    TCL_UNUSED(Tk_Window))		/* 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) {
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
2023
2024
2025
2026
2027
2028
2029
2030
2031

































































































































2032
2033
2034
2035
2036
2037









-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






    }
    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:
 */
Changes to generic/tkGC.c.
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
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. */
    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. */
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317







-
+







	 * 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);
    idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, (char *) 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);
Changes to generic/tkGeometry.c.
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99


100
101
102
103
104
105
106
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97


98
99
100
101
102
103
104
105
106







-
+



















-
-
+
+







 *	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.
 *	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. */
{
    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->lostSlaveProc != NULL)) {
	winPtr->geomMgrPtr->lostSlaveProc(winPtr->geomData, tkwin);
    }

    winPtr->geomMgrPtr = mgrPtr;
    winPtr->geomData = clientData;
}

/*
329
330
331
332
333
334
335
336
337


338
339
340
341
342
343
344
329
330
331
332
333
334
335


336
337
338
339
340
341
342
343
344







-
-
+
+







    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",
		    "cannot use geometry manager %s inside %s which already"
		    " has slaves managed by %s",
		    name, Tk_PathName(tkwin), winPtr->geomMgrName));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "FIGHT", NULL);
	}
	return TCL_ERROR;
    }

    winPtr->geomMgrName = (char *)ckalloc(strlen(name) + 1);
557
558
559
560
561
562
563
564

565
566
567
568
569
570
571
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571







-
+







 *	container, then this procedure has no effect.
 *
 *----------------------------------------------------------------------
 */

void
Tk_UnmaintainGeometry(
    Tk_Window window,		/* WIndow for geometry management. */
    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;
Changes to generic/tkGet.c.
467
468
469
470
471
472
473

474
475
476
477
478
479
480
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481







+







    Tk_Justify justify)		/* Justification style for which identifying
				 * string is desired. */
{
    switch (justify) {
    case TK_JUSTIFY_LEFT: return "left";
    case TK_JUSTIFY_RIGHT: return "right";
    case TK_JUSTIFY_CENTER: return "center";
    default: break;
    }
    return "unknown justification style";
}

/*
 *----------------------------------------------------------------------
 *
690
691
692
693
694
695
696





697
698
699
700
701
702
703
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709







+
+
+
+
+







				 * units. */
    const char *string,		/* String describing a number of pixels. */
    double *doublePtr)		/* Place to store converted result. */
{
    char *end;
    double d;

    if (!tkwin) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad screen"));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "FRACTIONAL_PIXELS", NULL);
	return TCL_ERROR;
    }
    d = strtod((char *) string, &end);
    if (end == string) {
	goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
Changes to generic/tkGrab.c.
12
13
14
15
16
17
18


19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36







+
+








-
+








#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#else
#include "tkMacOSXInt.h"
#endif

/*
 * The grab state machine has four states: ungrabbed, button pressed, grabbed,
 * and button pressed while grabbed. In addition, there are three pieces of
 * grab state information: the current grab window, the current restrict
 * window, and whether the mouse is captured.
 *
 * The current grab window specifies the point in the Tk window heirarchy
 * The current grab window specifies the point in the Tk window hierarchy
 * above which pointer events will not be reported. Any window within the
 * subtree below the grab window will continue to receive events as normal.
 * Events outside of the grab tree will be reported to the grab window.
 *
 * If the current restrict window is set, then all pointer events will be
 * reported only to the restrict window. The restrict window is normally set
 * during an automatic button grab.
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190







-
+







    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int globalGrab;
    Tk_Window tkwin;
    TkDisplay *dispPtr;
    const char *arg;
    int index;
    TkSizeT len;
    int len;
    static const char *const optionStrings[] = {
	"current", "release", "set", "status", NULL
    };
    static const char *const flagStrings[] = {
	"-global", NULL
    };
    enum options {
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227







-
+







	return TCL_ERROR;
    }

    /*
     * First check for a window name or "-global" as the first argument.
     */

    arg = TkGetStringFromObj(objv[1], &len);
    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);
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291







-
+








-
+







	    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)
		Tcl_SetObjResult(interp, TkNewWindowObj((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(
		    Tcl_ListObjAppendElement(NULL, resultObj, TkNewWindowObj(
			    (Tk_Window) dispPtr->eventualGrabWinPtr));
		}
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	return TCL_OK;

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
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







-
-
-











-







 *----------------------------------------------------------------------
 *
 * 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. */
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
771
772
773
774
775
776
777










778
779
780
781




782
783
784
785
786
787
788







-
-
-
-
-
-
-
-
-
-




-
-
-
-







		    && (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
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
797
798
799
800
801
802
803







804
805
806
807
808
809
810







-
-
-
-
-
-
-







	    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.
892
893
894
895
896
897
898
899

900
901
902
903
904
905
906
869
870
871
872
873
874
875

876
877
878
879
880
881
882
883







-
+







		}
		dispPtr->buttonWinPtr = winPtr;
		return 1;
	    }
	} else {
	    if (eventPtr->xbutton.button != AnyButton &&
		    ((eventPtr->xbutton.state & ALL_BUTTONS)
		    == Tk_GetButtonMask(eventPtr->xbutton.button))) {
		    == TkGetButtonMask(eventPtr->xbutton.button))) {
		ReleaseButtonGrab(dispPtr);			/* Note 4. */
	    }
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;						/* Note 3. */
Changes to generic/tkGrid.c.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * tkGrid.c --
 *
 *	Grid based geometry manager.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272







-
+







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 Tcl_FreeProc	DestroyGrid;
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,
288
289
290
291
292
293
294
295
296


297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
288
289
290
291
292
293
294


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 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 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		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 */
    GridLostContentProc,		/* lostSlaveProc */
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GridCmd --
 *
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378


379
380
381
382
383
384
385
337
338
339
340
341
342
343





344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363










364
365
366
367
368
369
370
371
372







-
-
-
-
-




















-
-
-
-
-
-
-
-
-
-
+
+







{
    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);
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case GRID_ANCHOR:
	return GridAnchorCommand(tkwin, interp, objc, objv);
    case GRID_BBOX:
454
455
456
457
458
459
460
461



462
463
464
465
466
467
468
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455
456
457







-
+
+
+







	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 (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }

    if (objc == 3) {
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		Tk_NameOfAnchor(gridPtr?gridPtr->anchor:GRID_DEFAULT_ANCHOR),
		-1));
	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
509
510
511
512
513
514
515

516
517
518
519
520
521
522

523
524
525
526
527
528
529
530
531
532







-
+






-
+
+
+







    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??");
	Tcl_WrongNumArgs(interp, 2, objv, "master ?column row ?column row??");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }

    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;
651
652
653
654
655
656
657
658



659
660
661
662
663
664
665
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657
658







-
+
+
+







    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 = GetGrid(content))) {
	    continue;
	}
	if (contentPtr->containerPtr != NULL) {
	    /*
	     * For "forget", reset all the settings to their defaults
	     */

	    if (c == 'f') {
		contentPtr->column = -1;
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
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







-
+
+
+







-
+

-
+

-
+

-
+

-
+







    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 = GetGrid(content))) {
	return TCL_OK;
    }
    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));
	    TkNewWindowObj(contentPtr->containerPtr->tkwin));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-column", -1),
	    Tcl_NewWideIntObj(contentPtr->column));
	    Tcl_NewIntObj(contentPtr->column));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-row", -1),
	    Tcl_NewWideIntObj(contentPtr->row));
	    Tcl_NewIntObj(contentPtr->row));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-columnspan", -1),
	    Tcl_NewWideIntObj(contentPtr->numCols));
	    Tcl_NewIntObj(contentPtr->numCols));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-rowspan", -1),
	    Tcl_NewWideIntObj(contentPtr->numRows));
	    Tcl_NewIntObj(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);
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
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







-
+














-
+
+
+







    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");
	Tcl_WrongNumArgs(interp, 2, objv, "master 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 = GetGrid(container))) {
	return TCL_OK;
    }
    if (containerPtr->containerDataPtr == NULL) {
	Tcl_SetObjResult(interp, NewPairObj(-1, -1));
	return TCL_OK;
    }
    gridPtr = containerPtr->containerDataPtr;

    /*
897
898
899
900
901
902
903
904



905
906
907
908
909
910
911
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910







-
+
+
+







	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 (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }
    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;
994
995
996
997
998
999
1000
1001

1002
1003
1004
1005
1006
1007
1008
993
994
995
996
997
998
999

1000
1001
1002
1003
1004
1005
1006
1007







-
+







    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 ...?");
	Tcl_WrongNumArgs(interp, 2, objv, "master index ?-option value ...?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

1019
1020
1021
1022
1023
1024
1025
1026



1027
1028
1029
1030
1031
1032
1033
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
1032
1033
1034







-
+
+
+







	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);
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }
    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));
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
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







-
+


-
+






-
+
















-
+


-
+







-
+







		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_NewIntObj(minsize));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-pad", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(pad));
	    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_NewWideIntObj(weight));
	    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_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(
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].minSize : 0));
	} else if (index == ROWCOL_WEIGHT) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
	    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_NewWideIntObj(
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].pad : 0));
	}
	Tcl_DecrRefCount(listCopy);
	return TCL_OK;
    }

    for (j = 0; j < lObjc; j++) {
1135
1136
1137
1138
1139
1140
1141
1142



1143
1144
1145
1146
1147

1148
1149
1150
1151
1152
1153
1154
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1157







-
+
+
+




-
+







	    allContent = 1;
	} else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &content)
		== TCL_OK) {
	    /*
	     * Is it gridded in this container?
	     */

	    contentPtr = GetGrid(content);
	    if (!(contentPtr = GetGrid(content))) {
		continue;
	    }
	    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_SetErrorCode(interp, "TK", "GRID", "NOT_MASTER", 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);
1318
1319
1320
1321
1322
1323
1324
1325



1326
1327
1328
1329
1330
1331
1332
1321
1322
1323
1324
1325
1326
1327

1328
1329
1330
1331
1332
1333
1334
1335
1336
1337







-
+
+
+







	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 = GetGrid(container))) {
	return TCL_OK;
    }

    if (containerPtr->containerDataPtr != NULL) {
	SetGridSize(containerPtr);
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, NewPairObj(
		MAX(gridPtr->columnEnd, gridPtr->columnMax),
		MAX(gridPtr->rowEnd, gridPtr->rowMax)));
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
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







-
+
+
+












-
+







	    row = value;
	}
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }

    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_ListObjAppendElement(interp,res, TkNewWindowObj(contentPtr->tkwin));
    }
    Tcl_SetObjResult(interp, res);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
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







-
+
+



-
+

















+
+
+
+








/*
 *----------------------------------------------------------------------
 *
 * GetGrid --
 *
 *	This internal procedure is used to locate a Grid structure for a given
 *	window, creating one if one doesn't exist already.
 *	window, creating one if one doesn't exist already, except if the window
 *	is already dead.
 *
 * Results:
 *	The return value is a pointer to the Grid structure corresponding to
 *	tkwin.
 *	tkwin, or NULL when tkwin is already dead.
 *
 * Side effects:
 *	A new grid structure may be created. If so, then a callback is set up
 *	to clean things up when the window is deleted.
 *
 *----------------------------------------------------------------------
 */

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 (((TkWindow *) tkwin)->flags & TK_ALREADY_DEAD) {
	return NULL;
    }

    if (!dispPtr->gridInit) {
	Tcl_InitHashTable(&dispPtr->gridHashTable, TCL_ONE_WORD_KEYS);
	dispPtr->gridInit = 1;
    }

    /*
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2487
2488
2489
2490
2491
2492
2493

2494
2495
2496
2497
2498
2499
2500







-







    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;
}

/*
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2797
2798
2799
2800
2801
2802
2803



2804
2805
2806
2807
2808

2809
2810
2811
2812
2813
2814
2815







-
-
-





-








    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 --
2820
2821
2822
2823
2824
2825
2826
2827

2828
2829
2830



2831
2832
2833
2834
2835
2836
2837
2827
2828
2829
2830
2831
2832
2833

2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847







-
+



+
+
+







 *	Everything associated with the grid is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyGrid(
    void *memPtr)		/* Info about window that is now dead. */
    char *memPtr)		/* Info about window that is now dead. */
{
    Gridder *gridPtr = (Gridder *)memPtr;

    if (gridPtr->flags & REQUESTED_RELAYOUT) {
	Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
    }
    if (gridPtr->containerDataPtr != NULL) {
	if (gridPtr->containerDataPtr->rowPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> rowPtr);
	}
	if (gridPtr->containerDataPtr->columnPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> columnPtr);
	}
2895
2896
2897
2898
2899
2900
2901
2902

2903
2904
2905
2906
2907

2908
2909
2910
2911
2912
2913
2914
2905
2906
2907
2908
2909
2910
2911

2912
2913
2914
2915
2916

2917
2918
2919
2920
2921
2922
2923
2924







-
+




-
+







	    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));
		(char *)gridPtr->tkwin));
	if (gridPtr->flags & REQUESTED_RELAYOUT) {
	    Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
	}
	gridPtr->tkwin = NULL;
	Tcl_EventuallyFree(gridPtr, (Tcl_FreeProc *)DestroyGrid);
	Tcl_EventuallyFree(gridPtr, 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) {
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
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







-
+


-
+


















-
+
+
+



-
+
+
+







-
+
+
+








    /*
     * Count the number of windows, or window short-cuts.
     */

    firstChar = 0;
    for (numWindows=0, i=0; i < objc; i++) {
	TkSizeT length;
	int length;
	char prevChar = firstChar;

	string = TkGetStringFromObj(objv[i], &length);
	string = Tcl_GetStringFromObj(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 = GetGrid(content))) {
		    continue;
		}
		if (contentPtr->in != NULL) {
		    if (TkGetWindowFromObj(interp, content, contentPtr->in, &parent)
			    == TCL_OK) {
			containerPtr = GetGrid(parent);
			if (!(containerPtr = GetGrid(parent))) {
			    continue;
			}
			InitContainerData(containerPtr);
		    }
		}
	    }
	    if (containerPtr == NULL) {
		parent = Tk_Parent(content);
		if (parent != NULL) {
		    containerPtr = GetGrid(parent);
		    if (!(containerPtr = GetGrid(parent))) {
			continue;
		    }
		    InitContainerData(containerPtr);
		}
	    }
	    numWindows++;
	    continue;
    	}
	if (length > 1 && i == 0) {
3082
3083
3084
3085
3086
3087
3088
3089



3090
3091
3092
3093
3094
3095
3096
3098
3099
3100
3101
3102
3103
3104

3105
3106
3107
3108
3109
3110
3111
3112
3113
3114







-
+
+
+







	    return TCL_ERROR;
	}
	if (index == CONF_IN) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) !=
		    TCL_OK) {
		return TCL_ERROR;
	    }
	    containerPtr = GetGrid(other);
	    if (!(containerPtr = GetGrid(other))) {
		continue;
	    }
	    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])));
3159
3160
3161
3162
3163
3164
3165
3166



3167
3168
3169
3170
3171
3172
3173
3177
3178
3179
3180
3181
3182
3183

3184
3185
3186
3187
3188
3189
3190
3191
3192
3193







-
+
+
+







	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);
	if (!(contentPtr = GetGrid(content))) {
	    continue;
	}

	/*
	 * 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)."
3218
3219
3220
3221
3222
3223
3224
3225



3226
3227
3228
3229
3230
3231
3232
3238
3239
3240
3241
3242
3243
3244

3245
3246
3247
3248
3249
3250
3251
3252
3253
3254







-
+
+
+







		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);
		if (!(containerPtr = GetGrid(other))) {
		    continue;
		}
		InitContainerData(containerPtr);
		break;
	    case CONF_STICKY: {
		int sticky = StringToSticky(Tcl_GetString(objv[i+1]));

		if (sticky == -1) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
3325
3326
3327
3328
3329
3330
3331
3332



3333
3334
3335
3336
3337
3338
3339
3347
3348
3349
3350
3351
3352
3353

3354
3355
3356
3357
3358
3359
3360
3361
3362
3363







-
+
+
+







	 * 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);
	    if (!(containerPtr = GetGrid(parent))) {
		continue;
	    }
	    InitContainerData(containerPtr);
    	}

	if (contentPtr->containerPtr != NULL && contentPtr->containerPtr != containerPtr) {
            if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
                Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
            }
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
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







-
+















-
+








	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]),
			"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",
		    "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)) {
3458
3459
3460
3461
3462
3463
3464
3465

3466
3467
3468
3469
3470
3471
3472
3482
3483
3484
3485
3486
3487
3488

3489
3490
3491
3492
3493
3494
3495
3496







-
+







	}
	if (firstChar != REL_VERT) {
	    continue;
	}

	if (containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't use '^', can't find container window", -1));
		    "can't use '^', cant find master", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Count the number of consecutive ^'s starting from this position.
	 */
3484
3485
3486
3487
3488
3489
3490
3491



3492
3493
3494
3495
3496
3497
3498
3508
3509
3510
3511
3512
3513
3514

3515
3516
3517
3518
3519
3520
3521
3522
3523
3524







-
+
+
+







	 */

	if (lastWindow == NULL) {
	    lastRow = defaultRow - 1;
	    lastColumn = 0;
	} else {
	    other = Tk_NameToWindow(interp, lastWindow, tkwin);
	    otherPtr = GetGrid(other);
	    if (!(otherPtr = GetGrid(other))) {
		continue;
	    }
	    lastRow = otherPtr->row + otherPtr->numRows - 2;
	    lastColumn = otherPtr->column + otherPtr->numCols;
	}

	lastColumn += numSkip;

	match = 0;
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
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







-
+







-
+








-
-
-





-







		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find content to extend with \"^\"", -1));
		    "can't find slave 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));
		"can't determine master 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;
}

/*
 *----------------------------------------------------------------------
3648
3649
3650
3651
3652
3653
3654
3655

3656
3657
3658
3659
3660


3661
3662
3663
3664
3665
3666
3667
3670
3671
3672
3673
3674
3675
3676

3677
3678
3679
3680


3681
3682
3683
3684
3685
3686
3687
3688
3689







-
+



-
-
+
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewPairObj(
    Tcl_WideInt val1, Tcl_WideInt val2)
    int val1, int val2)
{
    Tcl_Obj *ary[2];

    ary[0] = Tcl_NewWideIntObj(val1);
    ary[1] = Tcl_NewWideIntObj(val2);
    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
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







-
+



-
-
-
-
+
+
+
+










 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewQuadObj(
    Tcl_WideInt val1, Tcl_WideInt val2, Tcl_WideInt val3, Tcl_WideInt val4)
    int val1, int val2, int val3, int 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);
    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.
9
10
11
12
13
14
15




16
17
18
19
20
21
22
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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * 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 {
32
33
34
35
36
37
38


39
40
41
42
43
44
45
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







+
+







    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. */
    struct Image *prevPtr;	/* Previous 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.
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







-
+







static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for local functions:
 */

static void		ImageTypeThreadExitProc(ClientData clientData);
static void		DeleteImage(ImageModel *modelPtr);
static Tcl_FreeProc	DeleteImage;
static void		EventuallyDeleteImage(ImageModel *modelPtr,
			    int forgetImageHashNow);

/*
 *----------------------------------------------------------------------
 *
 * ImageTypeThreadExitProc --
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243







-
+







    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));
	    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,
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301







-
+







	/*
	 * 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);
		snprintf(idString, sizeof(idString), "image%d", dispPtr->imageId);
		name = idString;
	    } while (Tcl_FindCommand(interp, name, NULL, 0) != NULL);
	    firstOption = 3;
	} else {
	    TkWindow *topWin;

	    name = arg;
364
365
366
367
368
369
370







371
372




373
374
375
376
377
378
379
370
371
372
373
374
375
376
377
378
379
380
381
382
383


384
385
386
387
388
389
390
391
392
393
394







+
+
+
+
+
+
+
-
-
+
+
+
+







	    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 (oldimage) {
	    typedef int (OldCreateProc)(Tcl_Interp*, char*, int, char**,
		Tk_ImageType*, Tk_ImageModel, ClientData*);
	    i = ((OldCreateProc*)typePtr->createProc)(interp,
		(char*)name, objc, (char**)args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	} else {
	if (typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData) != TCL_OK){
	    i = typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	}
	if (i != TCL_OK){
	    EventuallyDeleteImage(modelPtr, 0);
	    Tcl_Release(modelPtr);
	    if (oldimage) {
		ckfree(args);
	    }
	    return TCL_ERROR;
	}
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427







-
+







	    if (hPtr == NULL) {
		goto alreadyDeleted;
	    }
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		goto alreadyDeleted;
	    }
	    DeleteImage(modelPtr);
	    DeleteImage((char *)modelPtr);
	}
	break;
    case IMAGE_NAMES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
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
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







-
+












-
+








	/*
	 * 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));
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(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));
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(modelPtr->width));
	    break;
	default:
	    Tcl_Panic("can't happen");
	}
	break;
    }
    return TCL_OK;
627
628
629
630
631
632
633




634
635
636
637
638
639
640
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659







+
+
+
+







    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;
    if (imagePtr->nextPtr) {
	imagePtr->nextPtr->prevPtr = imagePtr;
    }
    imagePtr->prevPtr = NULL;
    modelPtr->instancePtr = imagePtr;
    return (Tk_Image) imagePtr;

  noSuchImage:
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"image \"%s\" doesn't exist", name));
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
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







-









-
-
-
+
+
+
+
+

-
-
+
+
+

-







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;
    if (imagePtr->prevPtr) {
	imagePtr->prevPtr->nextPtr = imagePtr->nextPtr;
	if (imagePtr->nextPtr) {
	    imagePtr->nextPtr->prevPtr = imagePtr->prevPtr;
	}
    } else {
	while (prevPtr->nextPtr != imagePtr) {
	    prevPtr = prevPtr->nextPtr;
	modelPtr->instancePtr = imagePtr->nextPtr;
	if (modelPtr->instancePtr) {
	    modelPtr->instancePtr->prevPtr = NULL;
	}
	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.
     */
927
928
929
930
931
932
933
934

935
936
937
938
939
940
941
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961







-
+







    if (winPtr == NULL) {
	return;
    }
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	return;
    }
    DeleteImage((ImageModel *)Tcl_GetHashValue(hPtr));
    DeleteImage((char *)Tcl_GetHashValue(hPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * DeleteImage --
 *
950
951
952
953
954
955
956
957

958
959
960

961
962
963
964
965
966
967
970
971
972
973
974
975
976

977
978
979
980
981
982
983
984
985
986
987
988







-
+



+







 *	existing instances will not be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteImage(
    ImageModel *modelPtr)	/* Pointer to main data structure for image. */
    char *blockPtr)	/* Pointer to main data structure for image. */
{
    Image *imagePtr;
    Tk_ImageType *typePtr;
    ImageModel *modelPtr = (ImageModel *)blockPtr;

    typePtr = modelPtr->typePtr;
    modelPtr->typePtr = NULL;
    if (typePtr != NULL) {
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    typePtr->freeProc(imagePtr->instanceData, imagePtr->display);
1007
1008
1009
1010
1011
1012
1013
1014

1015
1016
1017
1018
1019
1020
1021
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042







-
+







				 * to vanish. */
{
    if (forgetImageHashNow) {
	modelPtr->hPtr = NULL;
    }
    if (!modelPtr->deleted) {
	modelPtr->deleted = 1;
	Tcl_EventuallyFree(modelPtr, (Tcl_FreeProc *) DeleteImage);
	Tcl_EventuallyFree(modelPtr, DeleteImage);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --
Changes to generic/tkImgBmap.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
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20

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


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59







-
+












-
+













-
-
+
+















-
+







/*
 * tkImgBmap.c --
 *
 *	This procedure implements images of type "bitmap" for Tk.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1999 by Scriptics Corporation.
 * 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.
 */

#include "tkInt.h"

/*
 * The following data structure represents the model for a bitmap
 * image:
 */

typedef struct {
typedef struct BitmapModel {
    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). */
    Tk_Uid fgUid;		/* Value of -foreground option. */
    Tk_Uid bgUid;		/* Value of -background option. */
    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
    int 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. */
71
72
73
74
75
76
77
78

79
80
81
82



83
84
85
86
87
88



89
90
91
92
93
94
95
71
72
73
74
75
76
77

78
79



80
81
82
83
84
85



86
87
88
89
90
91
92
93
94
95







-
+

-
-
-
+
+
+



-
-
-
+
+
+








/*
 * 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 char *name, int objc, 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,
			    void **clientDataPtr);
static void	*ImgBmapGet(Tk_Window tkwin, void *clientData);
static void		ImgBmapDisplay(void *clientData,
			    Display *display, Drawable drawable,
			    int imageX, int imageY, int width, int height,
			    int drawableX, int drawableY);
static void		ImgBmapFree(ClientData clientData, Display *display);
static void		ImgBmapDelete(ClientData clientData);
static int		ImgBmapPostscript(ClientData clientData,
static void		ImgBmapFree(void *clientData, Display *display);
static void		ImgBmapDelete(void *clientData);
static int		ImgBmapPostscript(void *clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psinfo, int x, int y,
			    int width, int height, int prepass);

Tk_ImageType tkBitmapImageType = {
    "bitmap",			/* name */
    ImgBmapCreate,		/* createProc */
104
105
106
107
108
109
110
111

112
113

114
115

116
117

118
119

120
121

122
123
124
125
126
127
128
104
105
106
107
108
109
110

111
112

113
114

115
116

117
118

119
120

121
122
123
124
125
126
127
128







-
+

-
+

-
+

-
+

-
+

-
+








/*
 * Information used for parsing configuration specs:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_UID, "-background", NULL, NULL,
	"", offsetof(BitmapModel, bgUid), 0, NULL},
	"", Tk_Offset(BitmapModel, bgUid), 0, NULL},
    {TK_CONFIG_STRING, "-data", NULL, NULL,
	NULL, offsetof(BitmapModel, dataString), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapModel, dataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	NULL, offsetof(BitmapModel, fileString), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_UID, "-foreground", NULL, NULL,
	"#000000", offsetof(BitmapModel, fgUid), 0, NULL},
	"#000000", Tk_Offset(BitmapModel, fgUid), 0, NULL},
    {TK_CONFIG_STRING, "-maskdata", NULL, NULL,
	NULL, offsetof(BitmapModel, maskDataString), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(BitmapModel, maskDataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-maskfile", NULL, NULL,
	NULL, offsetof(BitmapModel, maskFileString), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(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.
141
142
143
144
145
146
147
148
149
150



151
152
153

154
155
156
157
158
159
160
141
142
143
144
145
146
147



148
149
150
151
152

153
154
155
156
157
158
159
160







-
-
-
+
+
+


-
+







    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 int		ImgBmapCmd(void *clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static void		ImgBmapCmdDeletedProc(void *clientData);
static void		ImgBmapConfigureInstance(BitmapInstance *instancePtr);
static int		ImgBmapConfigureModel(BitmapModel *modelPtr,
			    int argc, Tcl_Obj *const objv[], int flags);
			    int objc, Tcl_Obj *const objv[], int flags);
static int		NextBitmapWord(ParseInfo *parseInfoPtr);

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCreate --
 *
170
171
172
173
174
175
176
177
178


179
180

181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

204
205
206
207
208
209
210
170
171
172
173
174
175
176


177
178
179

180
181
182

183
184
185
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
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
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    const Tk_ImageType *typePtr,/* Pointer to our type record (not used). */
    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
    void **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) {
    if (ImgBmapConfigureModel(modelPtr, objc, objv, 0) != TCL_OK) {
	ImgBmapDelete(modelPtr);
	return TCL_ERROR;
    }
    *clientDataPtr = modelPtr;
    return TCL_OK;
}

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260
261
234
235
236
237
238
239
240

241





242

243

244
245

246
247
248
249
250
251
252







-

-
-
-
-
-

-
+
-


-







    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) {
	    configSpecs, objc, (const char **) objv, (char *) modelPtr, flags|TK_CONFIG_OBJS) != 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) {
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
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







-
+

-
+
+




+











-
-
-
-







	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);
	expandedFileName = Tcl_TranslateFileName(NULL, fileName, &buffer);
	if (expandedFileName == NULL) {
	    return NULL;
	    Tcl_SetErrno(ENOENT);
	    goto cannotRead;
	}
	pi.chan = Tcl_OpenFileChannel(interp, expandedFileName, "r", 0);
	Tcl_DStringFree(&buffer);
	if (pi.chan == NULL) {
	cannotRead:
	    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;
	}
	if (Tcl_SetChannelOption(interp, pi.chan, "-encoding", "binary")
		!= TCL_OK) {
	    return NULL;
	}
    } else {
	pi.chan = NULL;
    }

    /*
747
748
749
750
751
752
753
754

755
756
757
758
759
760
761
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750







-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ImgBmapCmd(
    ClientData clientData,	/* Information about the image model. */
    void *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;
771
772
773
774
775
776
777
778

779
780
781
782

783
784
785

786
787
788
789
790
791
792
760
761
762
763
764
765
766

767
768
769
770

771
772
773

774
775
776
777
778
779
780
781







-
+



-
+


-
+







    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);
		(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);
		    configSpecs, (char *)modelPtr, NULL, 0);
	} else if (objc == 3) {
	    return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
		    configSpecs, (char *) modelPtr,
		    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");
808
809
810
811
812
813
814
815

816
817
818
819

820
821
822
823
824
825
826
797
798
799
800
801
802
803

804
805
806
807

808
809
810
811
812
813
814
815







-
+



-
+







 * Side effects:
 *	A data structure is set up for the instance (or, an existing instance
 *	is re-used for the new one).
 *
 *----------------------------------------------------------------------
 */

static ClientData
static void *
ImgBmapGet(
    Tk_Window tkwin,		/* Window in which the instance will be
				 * used. */
    ClientData modelData)	/* Pointer to our model structure for the
    void *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
879
880
881
882
883
884
885
886

887
888
889
890
891
892
893
868
869
870
871
872
873
874

875
876
877
878
879
880
881
882







-
+







 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDisplay(
    ClientData clientData,	/* Pointer to BitmapInstance structure for
    void *clientData,	/* Pointer to BitmapInstance structure for
				 * instance to be displayed. */
    Display *display,		/* Display on which to draw image. */
    Drawable drawable,		/* Pixmap or window in which to draw image. */
    int imageX, int imageY,	/* Upper-left corner of region within image to
				 * draw. */
    int width, int height,	/* Dimensions of region within image to draw. */
    int drawableX, int drawableY)
940
941
942
943
944
945
946
947

948
949
950
951
952
953
954
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943







-
+







 *	Internal data structures get cleaned up.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapFree(
    ClientData clientData,	/* Pointer to BitmapInstance structure for
    void *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) {
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
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







-
+

















-
+







 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDelete(
    ClientData modelData)	/* Pointer to BitmapModel structure for
    void *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);
    Tk_FreeOptions(configSpecs, (char *)modelPtr, NULL, 0);
    ckfree(modelPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCmdDeletedProc --
1043
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1032
1033
1034
1035
1036
1037
1038

1039
1040
1041
1042
1043
1044
1045
1046







-
+







 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapCmdDeletedProc(
    ClientData clientData)	/* Pointer to BitmapModel structure for
    void *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));
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091
1092
1064
1065
1066
1067
1068
1069
1070

1071

1072

1073
1074
1075
1076
1077
1078
1079







-

-
+
-







 */

static int
GetByte(
    Tcl_Channel chan)	/* The channel we read from. */
{
    char buffer;
    size_t size;

    size = Tcl_Read(chan, &buffer, 1);
    if (Tcl_Read(chan, &buffer, 1) != 1) {
    if (size != 1) {
	return EOF;
    } else {
	return buffer;
    }
}

/*
1186
1187
1188
1189
1190
1191
1192
1193

1194
1195
1196
1197
1198
1199
1200
1173
1174
1175
1176
1177
1178
1179

1180
1181
1182
1183
1184
1185
1186
1187







-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ImgBmapPostscript(
    ClientData clientData,
    void *clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tk_PostscriptInfo psinfo,
    int x, int y, int width, int height,
    int prepass)
{
    BitmapModel *modelPtr = (BitmapModel *)clientData;
Changes to generic/tkImgGIF.c.
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65







-
+







 * 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 */
    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
107
108
109
110
111
112
113
114
115


116
117
118
119
120
121
122
107
108
109
110
111
112
113


114
115
116
117
118
119
120
121
122







-
-
+
+







} 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);
typedef int (WriteBytesFunc) (void *clientData, const char *bytes,
			    int 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,
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145







-
+







			    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,
static int		CommonWriteGIF(Tcl_Interp *interp, void *clientData,
			    WriteBytesFunc *writeProc, Tcl_Obj *format,
			    Tk_PhotoImageBlock *blockPtr);

Tk_PhotoImageFormat tkImgFmtGIF = {
    "gif",		/* name */
    FileMatchGIF,	/* fileMatchProc */
    StringMatchGIF,	/* stringMatchProc */
183
184
185
186
187
188
189
190

191
192

193
194
195
196
197

198
199
200
201
202
203
204
183
184
185
186
187
188
189

190
191

192
193
194
195
196

197
198
199
200
201
202
203
204







-
+

-
+




-
+







			    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,
static int		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,
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,
			    size_t length);
			    int 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))
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290







-
+







     * 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;
    void *destination;
    WriteBytesFunc *writeProc;

    int clearCode;
    int eofCode;

    unsigned long currentAccumulated;
    int currentBits;
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318







-
+








/*
 * 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,
static void		Compress(int initBits, void *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);
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
364
365
366
347
348
349
350
351
352
353

354
355
356



357
358
359
360
361
362
363







-
+


-
-
-







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 */
    TCL_UNUSED(Tcl_Interp *))
{
    GIFImageConfig gifConf;
    (void)fileName;
    (void)format;
    (void)dummy;

    memset(&gifConf, 0, sizeof(GIFImageConfig));
    return ReadGIFHeader(&gifConf, chan, widthPtr, heightPtr);
}

/*
 *----------------------------------------------------------------------
435
436
437
438
439
440
441
442


443
444
445
446
447
448
449
450
451
452
453
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
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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







-
+
+














-
+
+





-
+
+








+
+
+
+
+
+
+
-
+







-
+
+







		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);
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "OPT_VALUE",
		    (char *) 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);
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "HEADER",
		(char *) 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);
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BOGUS_SIZE",
		(char *) NULL);
	return TCL_ERROR;
    }

    /*
     * Get the general colormap information.
     */

    if (Fread(gifConfPtr, buf, 1, 3, chan) != 3) {
	/*
	 * Bug [865af0148c]: 3 bytes should be there, but data ended before
	 */
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"GIF file truncated", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "TRUNCATED",
		(char *) NULL);
	return TCL_OK;
	return TCL_ERROR;
    }
    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);
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP",
		    (char *) NULL);
	    return TCL_ERROR;
	}
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
    }
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
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







-
+







-
+
+












-
+







-
+









-
+







	    /*
	     * 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);
		    (char *) 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);
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "NO_DATA",
		    (char *) 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);
			(char *) 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);
			(char *) 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);
			(char *) NULL);
		goto error;
	    }
	    break;
	default:
	    /*
	     * Not a valid start character; ignore it.
	     */
582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605







-
+







	     */

	    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);
			    "COLOR_MAP", (char *) NULL);
		    goto error;
		}
	    }

	    /*
	     * If we've not yet allocated a trash buffer, do so now.
	     */
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
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







+
+
+
+
+
+
+














-
+
+







	     * common case.
	     */

	    if (ReadImage(gifConfPtr, interp, trashBuffer, chan, imageWidth,
		    imageHeight, colorMap, 0, 0, 0, -1) != TCL_OK) {
		goto error;
	    }

	    /*
	     * This extension starts a new scope, so Graphic control Extension
	     * data should be cleared
	     */
	    transparent = -1;

	    continue;
	}
	break;
    }

    /*
     * 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);
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP",
		    (char *) 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.
669
670
671
672
673
674
675

676
677
678
679
680
681
682
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700







+







	srcY = 0;
    }
    if (height > imageHeight) {
	height = imageHeight;
    }

    if ((width > 0) && (height > 0)) {
	unsigned char* pixelPtr;
	Tk_PhotoImageBlock block;

	/*
	 * Read the data and put it into the photo buffer for display by the
	 * general image machinery.
	 */

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
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







-
-
-
+
+
+


+



-
+


+


-
+


-
+







	    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);
	pixelPtr = (unsigned char*)ckalloc(nBytes);
	if (pixelPtr) {
	    memset(pixelPtr, 0, nBytes);
	}

	block.pixelPtr = pixelPtr;
	if (ReadImage(gifConfPtr, interp, block.pixelPtr, chan, imageWidth,
		imageHeight, colorMap, srcX, srcY, BitSet(buf[8], INTERLACE),
		transparent) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    ckfree(pixelPtr);
	    goto error;
	}
	block.pixelPtr += srcX * block.pixelSize + srcY * block.pitch;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    ckfree(pixelPtr);
	    goto error;
	}
	ckfree(block.pixelPtr);
	ckfree(pixelPtr);
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */

753
754
755
756
757
758
759
760

761
762
763

764
765
766
767
768

769
770
771
772
773
774
775
773
774
775
776
777
778
779

780
781
782

783
784


785

786
787
788
789
790
791
792
793







-
+


-
+

-
-

-
+








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 */
    Tcl_Interp *interp)		/* not used */
{
    unsigned char *data, header[10];
    TkSizeT got, length;
    int got, length;
    MFile handle;
    (void)format;
    (void)dummy;

    data = TkGetByteArrayFromObj(dataObj, &length);
    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
845
846
847
848
849
850
851

852
853

854
855
856
857
858
859
860
861







-
+

-
+







    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;
    int length;
    const char *xferFormat;
    unsigned char *data = TkGetByteArrayFromObj(dataObj, &length);
    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
936
937
938
939
940
941
942

943
944
945
946
947
948
949
950







-
+







    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) {
	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];
944
945
946
947
948
949
950





951
952
953
954
955
956
957
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980







+
+
+
+
+







    unsigned char *buf,
    int *transparent)
{
    int count;

    switch (label) {
    case 0x01:			/* Plain Text Extension */
	/*
	 * This extension starts a new scope, so Graphic control Extension
	 * data should be cleared
	 */
	*transparent = -1;
	break;

    case 0xff:			/* Application Extension */
	break;

    case 0xfe:			/* Comment Extension */
	do {
984
985
986
987
988
989
990
991

992
993
994
995

996
997
998
999
1000
1001
1002
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
1025







-
+



-
+







GetDataBlock(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    unsigned char *buf)
{
    unsigned char count;

    if (((size_t)Fread(gifConfPtr, &count, 1, 1, chan) + 1) < 2) {
    if (Fread(gifConfPtr, &count, 1, 1, chan) <= 0) {
	return -1;
    }

    if ((count != 0) && (((size_t)Fread(gifConfPtr, buf, count, 1, chan) + 1) < 2)) {
    if ((count != 0) && (Fread(gifConfPtr, buf, count, 1, chan) <= 0)) {
	return -1;
    }

    return count;
}

/*
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
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







-
+
+














-
-





-
+







-
+
+







ReadImage(
    GIFImageConfig *gifConfPtr,
    Tcl_Interp *interp,
    unsigned char *imagePtr,
    Tcl_Channel chan,
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
    int srcX, int srcY,
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    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) {
    if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) {
	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);
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "MALFORMED",
		(char *) NULL);
	return TCL_ERROR;
    }

    if (transparent != -1) {
	cmap[transparent][CM_RED] = 0;
	cmap[transparent][CM_GREEN] = 0;
	cmap[transparent][CM_BLUE] = 0;
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
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







-
-
-
+
+
+

-
+

-
+



-
-
+
+





-
+







		     */

		    *top++ = append[code];
		    code = prefix[code];
		}
		firstCode = append[code];

	        /*
	         * Push the head of the code onto the stack.
	         */
		/*
		 * Push the head of the code onto the stack.
		 */

	        *top++ = firstCode;
		*top++ = firstCode;

                if (maxCode < (1 << MAX_LWZ_BITS)) {
		if (maxCode < (1 << MAX_LWZ_BITS)) {
		    /*
		     * If there's still room in our codes table, add a new entry.
		     * Otherwise don't, and keep using the current table.
                     * See DEFERRED CLEAR CODE IN LZW COMPRESSION in the GIF89a
                     * specification.
		     * See DEFERRED CLEAR CODE IN LZW COMPRESSION in the GIF89a
		     * specification.
		     */

		    prefix[maxCode] = oldCode;
		    append[maxCode] = firstCode;
		    maxCode++;
                }
		}

		/*
		 * maxCode tells us the maximum code value we can accept. If
		 * we see that we need more bits to represent it than we are
		 * requesting from the unpacker, we need to increase the
		 * number we ask for.
		 */
1395
1396
1397
1398
1399
1400
1401
1402

1403
1404
1405
1406
1407
1408
1409
1418
1419
1420
1421
1422
1423
1424

1425
1426
1427
1428
1429
1430
1431
1432







-
+







 *----------------------------------------------------------------------
 */

static void
mInit(
    unsigned char *string,	/* string containing initial mmencoded data */
    MFile *handle,		/* mmdecode "file" handle */
    size_t length)			/* Number of bytes in string */
    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
1444
1445
1446
1447
1448
1449
1450

1451
1452
1453
1454
1455
1456
1457


1458
1459
1460
1461
1462
1463
1464
1465
1466







-
+






-
-
+
+







 *
 * Side effects:
 *	The base64 handle will change state.
 *
 *----------------------------------------------------------------------
 */

static size_t
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 */
{
    int c;
    size_t i, count = chunkSize * numChunks;
    int i, c;
    int count = chunkSize * numChunks;

    for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
	*dst++ = c;
    }
    return i;
}

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
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







-
+













-
-
+
+







 *	a base64 encoded string.
 *
 * Results: - same as POSIX fread() or Tcl Tcl_Read()
 *
 *----------------------------------------------------------------------
 */

static size_t
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 + 1 < 2) || (handle->length < hunk*count)) {
	    return (size_t)-1;
	if ((handle->length <= 0) || ((size_t)handle->length < hunk * count)) {
	    return -1;
	}
	memcpy(dst, handle->data, hunk * count);
	handle->data += hunk * count;
	handle->length -= hunk * count;
	return hunk * count;
    }

1642
1643
1644
1645
1646
1647
1648
1649
1650


1651
1652
1653
1654
1655
1656
1657
1665
1666
1667
1668
1669
1670
1671


1672
1673
1674
1675
1676
1677
1678
1679
1680







-
-
+
+







    Tcl_Channel chan = NULL;
    int result;

    chan = Tcl_OpenFileChannel(interp, (char *) filename, "w", 0644);
    if (!chan) {
	return TCL_ERROR;
    }
    if (Tcl_SetChannelOption(interp, chan, "-translation",
	    "binary") != TCL_OK) {
    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    result = CommonWriteGIF(interp, chan, WriteToChannel, format, blockPtr);

    if (Tcl_Close(interp, chan) == TCL_ERROR) {
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
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







-
+

-
+

-
+






-
+

-
+

-
+













-
+









-







    if (result == TCL_OK) {
	Tcl_SetObjResult(interp, objPtr);
    }
    Tcl_DecrRefCount(objPtr);
    return result;
}

static size_t
static int
WriteToChannel(
    ClientData clientData,
    void *clientData,
    const char *bytes,
    size_t byteCount)
    int byteCount)
{
    Tcl_Channel handle = (Tcl_Channel)clientData;

    return Tcl_Write(handle, bytes, byteCount);
}

static size_t
static int
WriteToByteArray(
    ClientData clientData,
    void *clientData,
    const char *bytes,
    size_t byteCount)
    int 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,
    void *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;
1750
1751
1752
1753
1754
1755
1756
1757


1758
1759
1760
1761
1762
1763
1764
1772
1773
1774
1775
1776
1777
1778

1779
1780
1781
1782
1783
1784
1785
1786
1787







-
+
+







    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);
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLORFUL",
		(char *) NULL);
	return TCL_ERROR;
    }
    if (state.num<2) {
	state.num = 2;
    }
    c = LSB(width);
    writeProc(handle, (char *) &c, 1);
1962
1963
1964
1965
1966
1967
1968
1969

1970
1971
1972
1973
1974
1975
1976
1985
1986
1987
1988
1989
1990
1991

1992
1993
1994
1995
1996
1997
1998
1999







-
+







 *              James A. Woods          (decvax!ihnp4!ames!jaw)
 *              Joe Orost               (decvax!vax135!petsd!joe)
 */

static void
Compress(
    int initialBits,
    ClientData handle,
    void *handle,
    WriteBytesFunc *writeProc,
    ifunptr readValue,
    GifWriterState *statePtr)
{
    long fcode, ent, disp, hSize, i = 0;
    int c, hshift;
    GIFState_t state;
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: */
Changes to generic/tkImgPNG.c.
8
9
10
11
12
13
14
15
16


17
18
19
20
21
22
23
8
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"

#define	PNG_INT32(a,b,c,d)	\
	(((long)(a) << 24) | ((long)(b) << 16) | ((long)(c) << 8) | (long)(d))
#define	PNG_UINT32(a,b,c,d)	\
	(((unsigned long)(a) << 24) | ((unsigned long)(b) << 16) | ((unsigned long)(c) << 8) | (unsigned 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.
 */

41
42
43
44
45
46
47
48
49
50
51




52
53
54
55
56
57
58






59
60
61
62


63
64

65
66
67
68



69
70

71
72

73
74
75
76



77
78
79
80
81
82
83
41
42
43
44
45
46
47




48
49
50
51
52






53
54
55
56
57
58
59
60


61
62
63

64
65



66
67
68
69

70
71

72
73



74
75
76
77
78
79
80
81
82
83







-
-
-
-
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+


-
-
+
+

-
+

-
-
-
+
+
+

-
+

-
+

-
-
-
+
+
+








/*
 * 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_IDAT	PNG_UINT32('I','D','A','T')	/* Pixel data. */
#define CHUNK_IEND	PNG_UINT32('I','E','N','D')	/* End of Image. */
#define CHUNK_IHDR	PNG_UINT32('I','H','D','R')	/* Header. */
#define CHUNK_PLTE	PNG_UINT32('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
#define CHUNK_bKGD	PNG_UINT32('b','K','G','D')	/* Background Color */
#define CHUNK_cHRM	PNG_UINT32('c','H','R','M')	/* Chroma values. */
#define CHUNK_gAMA	PNG_UINT32('g','A','M','A')	/* Gamma. */
#define CHUNK_hIST	PNG_UINT32('h','I','S','T')	/* Histogram. */
#define CHUNK_iCCP	PNG_UINT32('i','C','C','P')	/* Color profile. */
#define CHUNK_iTXt	PNG_UINT32('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
#define CHUNK_oFFs	PNG_UINT32('o','F','F','s')	/* Image offset. */
#define CHUNK_pCAL	PNG_UINT32('p','C','A','L')	/* Pixel calibration
							 * data. */
#define CHUNK_pHYs	PNG_INT32('p','H','Y','s')	/* Physical pixel
#define CHUNK_pHYs	PNG_UINT32('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
#define CHUNK_sBIT	PNG_UINT32('s','B','I','T')	/* Significant bits */
#define CHUNK_sCAL	PNG_UINT32('s','C','A','L')	/* Physical scale. */
#define CHUNK_sPLT	PNG_UINT32('s','P','L','T')	/* Suggested
							 * palette. */
#define CHUNK_sRGB	PNG_INT32('s','R','G','B')	/* Standard RGB space
#define CHUNK_sRGB	PNG_UINT32('s','R','G','B')	/* Standard RGB space
							 * declaration. */
#define CHUNK_tEXt	PNG_INT32('t','E','X','t')	/* Plain Latin-1
#define CHUNK_tEXt	PNG_UINT32('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
#define CHUNK_tIME	PNG_UINT32('t','I','M','E')	/* Time stamp. */
#define CHUNK_tRNS	PNG_UINT32('t','R','N','S')	/* Transparency. */
#define CHUNK_zTXt	PNG_UINT32('z','T','X','t')	/* Compressed Latin-1
							 * text. */

/*
 * Color flags.
 */

#define PNG_COLOR_INDEXED	1
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







    /*
     * 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. */
    int 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.
192
193
194
195
196
197
198
199


200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218
219
220

221
222
223

224
225
226

227
228
229
230
231
232
233
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

218
219
220

221
222
223

224
225
226

227
228
229
230
231
232
233
234







-
+
+

















-
+


-
+


-
+


-
+







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);
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
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 char *destPtr, int destSz,
			    unsigned long *crcPtr);
static int		ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned char *destPtr, int destSz,
			    unsigned long *crcPtr);
static int		ReadData(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned char *destPtr, int destSz,
			    unsigned long *crcPtr);
static int		ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr,
			    size_t *sizePtr, unsigned long *typePtr,
			    int *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,
246
247
248
249
250
251
252
253

254
255

256
257
258
259
260
261
262
247
248
249
250
251
252
253

254
255

256
257
258
259
260
261
262
263







-
+

-
+







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);
			    const unsigned char *dataPtr, int dataSize);
static int		WriteData(Tcl_Interp *interp, PNGImage *pngPtr,
			    const unsigned char *srcPtr, size_t srcSz,
			    const unsigned char *srcPtr, int 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);
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330







-
+







     * reading with ReadData().
     */

    if (objPtr) {
	Tcl_IncrRefCount(objPtr);
	pngPtr->objDataPtr = objPtr;
	pngPtr->strDataBuf =
		TkGetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
		Tcl_GetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
    }

    /*
     * Initialize the palette transparency table to fully opaque.
     */

    memset(pngPtr->palette, 255, sizeof(pngPtr->palette));
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441







-
+







 */

static int
ReadBase64(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    int 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,
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468







-
+







	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 */
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
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







-
+






-
+







-
+







 */

static int
ReadByteArray(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    int destSz,
    unsigned long *crcPtr)
{
    /*
     * Check to make sure the number of requested bytes are available.
     */

    if ((size_t)pngPtr->strDataLen < destSz) {
    if (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);
	int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	memcpy(destPtr, pngPtr->strDataBuf, blockSz);

	pngPtr->strDataBuf += blockSz;
	pngPtr->strDataLen -= blockSz;

	if (crcPtr) {
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
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







-
+









-
+


-
+







 */

static int
ReadData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    size_t destSz,
    int 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);
	int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
	if (blockSz == TCL_IO_FAILURE) {
	if (blockSz == -1) {
	    /* TODO: failure info... */
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "channel read failed: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;
	}

	/*
690
691
692
693
694
695
696
697

698
699
700
701
702
703
704
691
692
693
694
695
696
697

698
699
700
701
702
703
704
705







-
+







{
    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]);
    *resultPtr = PNG_UINT32(p[0], p[1], p[2], p[3]);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
854
855
856
857
858
859
860
861

862
863
864
865
866
867
868
855
856
857
858
859
860
861

862
863
864
865
866
867
868
869







-
+







 *----------------------------------------------------------------------
 */

static int
ReadChunkHeader(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    size_t *sizePtr,
    int *sizePtr,
    unsigned long *typePtr,
    unsigned long *crcPtr)
{
    unsigned long chunkType = 0;
    int chunkSz = 0;
    unsigned long crc = 0;

882
883
884
885
886
887
888
889

890
891
892
893
894
895
896
883
884
885
886
887
888
889

890
891
892
893
894
895
896
897







-
+







	 * 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]);
	temp = PNG_UINT32(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;
907
908
909
910
911
912
913
914

915
916
917
918
919
920
921
908
909
910
911
912
913
914

915
916
917
918
919
920
921
922







-
+







	    return TCL_ERROR;
	}

	/*
	 * Convert it to a host-order integer for simple comparison.
	 */

	chunkType = PNG_INT32(pc[0], pc[1], pc[2], pc[3]);
	chunkType = PNG_UINT32(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.
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
973
974
975
976
977
978
979

980
981
982
983
984
985
986
987







-
+








	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)) {
		if (chunkType & PNG_UINT32(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",
1235
1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1250







-
+







static int
ReadIHDR(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char sigBuf[PNG_SIG_SZ];
    unsigned long chunkType;
    size_t chunkSz;
    int chunkSz;
    unsigned long crc;
    unsigned long width, height;
    int mismatch;

    /*
     * Read the appropriate number of bytes for the PNG signature.
     */
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1274







-
+







    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->strDataBuf = Tcl_GetByteArrayFromObj(pngPtr->objDataPtr,
		&pngPtr->strDataLen);
	pngPtr->base64Data = pngPtr->strDataBuf;

	if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

1704
1705
1706
1707
1708
1709
1710
1711

1712
1713

1714
1715
1716
1717
1718
1719
1720
1705
1706
1707
1708
1709
1710
1711

1712
1713

1714
1715
1716
1717
1718
1719
1720
1721







-
+

-
+








static int
UnfilterLine(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char *thisLine =
	    Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, NULL);
	    Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, (int *)NULL);
    unsigned char *lastLine =
	    Tcl_GetByteArrayFromObj(pngPtr->lastLineObj, NULL);
	    Tcl_GetByteArrayFromObj(pngPtr->lastLineObj, (int *)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

1836
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849
1850
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849
1850
1851







-
+







    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);
    unsigned char *p = Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, (int *)NULL);

    p++;
    if (UnfilterLine(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (pngPtr->currentLine >= pngPtr->block.height) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
2093
2094
2095
2096
2097
2098
2099
2100

2101
2102
2103
2104
2105
2106
2107
2094
2095
2096
2097
2098
2099
2100

2101
2102
2103
2104
2105
2106
2107
2108







-
+







    unsigned long crc)
{
    /*
     * Process IDAT contents until there is no more in this chunk.
     */

    while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) {
	TkSizeT len1, len2;
	int len1, len2;

	/*
	 * Read another block of input into the zlib stream if data remains.
	 */

	if (chunkSz) {
	    Tcl_Obj *inputObj = NULL;
2142
2143
2144
2145
2146
2147
2148
2149

2150
2151
2152
2153
2154

2155
2156

2157
2158
2159
2160
2161
2162
2163
2143
2144
2145
2146
2147
2148
2149

2150
2151
2152
2153
2154

2155
2156

2157
2158
2159
2160
2161
2162
2163
2164







-
+




-
+

-
+








	/*
	 * 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);
	Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len1);
	if (Tcl_ZlibStreamGet(pngPtr->stream, pngPtr->thisLineObj,
		pngPtr->phaseSize - len1) == TCL_ERROR) {
	    return TCL_ERROR;
	}
	TkGetByteArrayFromObj(pngPtr->thisLineObj, &len2);
	Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len2);

	if (len2 == (TkSizeT)pngPtr->phaseSize) {
	if (len2 == 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;
2291
2292
2293
2294
2295
2296
2297
2298

2299
2300
2301
2302
2303
2304
2305
2292
2293
2294
2295
2296
2297
2298

2299
2300
2301
2302
2303
2304
2305
2306







-
+







    PNGImage *pngPtr)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    static const char *const fmtOptions[] = {
	"-alpha", NULL
    };
    enum fmtOptionsEnum {
    enum fmtOptions {
	OPT_ALPHA
    };

    /*
     * Extract elements of format specification as a list.
     */

2328
2329
2330
2331
2332
2333
2334
2335

2336
2337
2338
2339
2340
2341
2342
2329
2330
2331
2332
2333
2334
2335

2336
2337
2338
2339
2340
2341
2342
2343







-
+







	    Tcl_WrongNumArgs(interp, 1, objv, "value");
	    return TCL_ERROR;
	}

	objc--;
	objv++;

	switch ((enum fmtOptionsEnum) optIndex) {
	switch ((enum fmtOptions) 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)) {
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382










2383
2384

2385

2386
2387
2388
2389
2390
2391
2392
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







-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+


+
-
+







 *	dimensions and contents may change.
 *
 *----------------------------------------------------------------------
 */

static int
DecodePNG(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,
    int destY)
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    PNGImage *pngPtr,		/* PNG image information record. */
    Tcl_Obj *fmtObj,		/* User-specified format object, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    unsigned long chunkType;
    int result;
    size_t chunkSz;
    int chunkSz;
    unsigned long crc;

    /*
     * Parse the PNG signature and IHDR (header) chunk.
     */

    if (ReadIHDR(interp, pngPtr) == TCL_ERROR) {
2479
2480
2481
2482
2483
2484
2485
2486
2487


2488
2489
2490
2491
2492
2493
2494
2485
2486
2487
2488
2489
2490
2491


2492
2493
2494
2495
2496
2497
2498
2499
2500







-
-
+
+








    /*
     * 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) {
    if (Tk_PhotoExpand(interp, imageHandle, destX + width,
	    destY + 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.
     */
2520
2521
2522
2523
2524
2525
2526
2527

2528
2529
2530
2531
2532
2533
2534
2526
2527
2528
2529
2530
2531
2532

2533
2534
2535
2536
2537
2538
2539
2540







-
+







    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);
	Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)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.
2634
2635
2636
2637
2638
2639
2640

2641

2642
2643
2644
2645



2646
2647

2648
2649
2650
2651
2652
2653
2654
2640
2641
2642
2643
2644
2645
2646
2647

2648




2649
2650
2651


2652
2653
2654
2655
2656
2657
2658
2659







+
-
+
-
-
-
-
+
+
+
-
-
+








    ApplyAlpha(pngPtr);

    /*
     * Copy the decoded image block into the Tk photo image.
     */

    pngPtr->block.pixelPtr += srcX * pngPtr->block.pixelSize + srcY * pngPtr->block.pitch;
    if (Tk_PhotoPutBlock(interp, imageHandle, &pngPtr->block, destX, destY,
    result = Tk_PhotoPutBlock(interp, imageHandle, &pngPtr->block, destX, destY,
	    pngPtr->block.width, pngPtr->block.height,
	    TK_PHOTO_COMPOSITE_SET) == TCL_ERROR) {
	return TCL_ERROR;
    }
	    width, height, TK_PHOTO_COMPOSITE_SET);
    pngPtr->block.pixelPtr -= srcX * pngPtr->block.pixelSize + srcY * pngPtr->block.pitch;


    return TCL_OK;
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * FileMatchPNG --
 *
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2677
2678
2679
2680
2681
2682
2683


2684
2685
2686
2687
2688
2689
2690







-
-







    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;
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
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







-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+



-
-
-
-
-




-
+







 *	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)
    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 *fmtObj,		/* User-specified format object, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    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);
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY, width, height, srcX, srcY);
    }

    CleanupPNGImage(&png);
    return result;
}

/*
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778

2779
2780
2781
2782
2783
2784
2785
2765
2766
2767
2768
2769
2770
2771

2772
2773
2774

2775
2776
2777
2778
2779
2780
2781
2782







-



-
+







    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);
    png.strDataBuf = Tcl_GetByteArrayFromObj(pObjData, &png.strDataLen);

    if (ReadIHDR(interp, &png) == TCL_OK) {
	*widthPtr = png.block.width;
	*heightPtr = png.block.height;
	match = 1;
    }

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
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







-
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+



-
-
-
-





-
+







 *	New data is added to the image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
StringReadPNG(
    Tcl_Interp *interp,
    Tcl_Interp* interp,		/* Interpreter to use for reporting errors. */
    Tcl_Obj *pObjData,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,
    int destY,
    int width,
    int height,
    int srcX,
    int srcY)
    Tcl_Obj *fmtObj,		/* User-specified format object, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    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);
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY, width, height, srcX, srcY);
    }

    CleanupPNGImage(&png);
    return result;
}

/*
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
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







-
+


-
+













-
+


-
+

-
+
















-
+







 */

static int
WriteData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    const unsigned char *srcPtr,
    size_t srcSz,
    int srcSz,
    unsigned long *crcPtr)
{
    if (!srcPtr || !srcSz) {
    if (!srcPtr || srcSz <= 0) {
	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;
	int objSz;
	unsigned char *destPtr;

	TkGetByteArrayFromObj(pngPtr->objDataPtr, &objSz);
	Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, &objSz);

	if (objSz + srcSz > INT_MAX) {
	if (objSz > INT_MAX - srcSz) {
	    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) {
    } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == -1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"write to channel failed: %s", Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    return TCL_OK;
}
2968
2969
2970
2971
2972
2973
2974
2975

2976
2977
2978
2979
2980
2981
2982
2961
2962
2963
2964
2965
2966
2967

2968
2969
2970
2971
2972
2973
2974
2975







-
+








static inline int
WriteChunk(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long chunkType,
    const unsigned char *dataPtr,
    size_t dataSize)
    int dataSize)
{
    unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0);
    int result = TCL_OK;

    /*
     * Write the length field for the chunk.
     */
3142
3143
3144
3145
3146
3147
3148
3149

3150
3151
3152
3153
3154
3155
3156
3135
3136
3137
3138
3139
3140
3141

3142
3143
3144
3145
3146
3147
3148
3149







-
+







    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tk_PhotoImageBlock *blockPtr)
{
    int rowNum, flush = TCL_ZLIB_NO_FLUSH, result;
    Tcl_Obj *outputObj;
    unsigned char *outputBytes;
    TkSizeT outputSize;
    int outputSize;

    /*
     * Filter and compress each row one at a time.
     */

    for (rowNum=0 ; rowNum < blockPtr->height ; rowNum++) {
	int colNum;
3234
3235
3236
3237
3238
3239
3240
3241

3242
3243
3244
3245
3246
3247
3248
3227
3228
3229
3230
3231
3232
3233

3234
3235
3236
3237
3238
3239
3240
3241







-
+








    /*
     * 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);
    outputBytes = Tcl_GetByteArrayFromObj(outputObj, &outputSize);
    result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize);
    Tcl_DecrRefCount(outputObj);
    return result;
}

/*
 *----------------------------------------------------------------------
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3460
3461
3462
3463
3464
3465
3466

3467
3468
3469
3470
3471
3472
3473







-







    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);
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502


3503
3504
3505
3506
3507
3508
3509
3481
3482
3483
3484
3485
3486
3487







3488
3489
3490
3491
3492
3493
3494
3495
3496







-
-
-
-
-
-
-
+
+







     */

    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) {
    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
	    != TCL_OK) {
	goto cleanup;
    }

    /*
     * Write the raw PNG data out to the file.
     */

3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3525
3526
3527
3528
3529
3530
3531

3532
3533
3534
3535
3536
3537
3538







-







    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) {
Changes to generic/tkImgPPM.c.
12
13
14
15
16
17
18




19
20
21
22
23
24
25
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29







+
+
+
+







 * Author: Paul Mackerras (paulus@cs.anu.edu.au),
 *	Department of Computer Science,
 *	Australian National University.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The maximum amount of memory to allocate for data read from the file. If we
 * need more than this, we do it in pieces.
 */

#define MAX_MEMORY	10000		/* don't allocate > 10KB */

138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+







    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;
    int 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));
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255







-
+







	    for (p = pixelPtr; count > 0; count--, p++) {
		*p = (((int) *p) * 255)/maxIntensity;
	    }
	} else if (maxIntensity > 0x00ff) {
	    unsigned char *p;
	    unsigned int value;

	    for (p = pixelPtr; count > 0; count--, p += 2) {
	    for (p = pixelPtr; count > 0; 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;
	    }
	}
	block.height = nLines;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310

311
312
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328
329



330
331
332
333
334
335
336
286
287
288
289
290
291
292

293

294
295
296
297
298
299
300
301
302
303
304
305
306





307


308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324



325
326
327
328
329
330
331
332
333
334







-
+
-













-
-
-
-
-
+
-
-
+









-
+






-
-
-
+
+
+







FileWritePPM(
    Tcl_Interp *interp,
    const char *fileName,
    TCL_UNUSED(Tcl_Obj *),
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    int w, h, greenOffset, blueOffset;
    int w, h, greenOffset, blueOffset, nBytes;
    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;
    }

    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }


    sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
    snprintf(header, sizeof(header), "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
    Tcl_Write(chan, header, -1);

    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) {
	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) == TCL_IO_FAILURE ||
			Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1) == TCL_IO_FAILURE ||
			Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) == TCL_IO_FAILURE) {
		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;
	}
    }
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386







-
+







    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;

    sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
    snprintf(header, sizeof(header), "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);

    /*
     * Construct a byte array of the right size with the header and
     * get a pointer to the data part of it.
     */

    size = strlen(header);
600
601
602
603
604
605
606
607
608


609
610
611
612
613
614
615
598
599
600
601
602
603
604


605
606
607
608
609
610
611
612
613







-
-
+
+







	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]);
	    for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2, dataBuffer += 2) {
		value = ((unsigned int)dataBuffer[0]) * 256 + ((unsigned int)dataBuffer[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,
760
761
762
763
764
765
766
767

768
769
770

771
772
773
774
775
776
777
758
759
760
761
762
763
764

765
766
767

768
769
770
771
772
773
774
775







-
+


-
+







				 * is stored here. */
    unsigned char **dataBufferPtr,
    int *dataSizePtr)
{
#define BUFFER_SIZE 1000
    char buffer[BUFFER_SIZE], c;
    int i, numFields, type = 0;
    TkSizeT dataSize;
    int dataSize;
    unsigned char *dataBuffer;

    dataBuffer = TkGetByteArrayFromObj(dataPtr, &dataSize);
    dataBuffer = Tcl_GetByteArrayFromObj(dataPtr, &dataSize);

    /*
     * Read 4 space-separated fields from the string, ignoring comments (any
     * line that starts with "#").
     */

    if (dataSize-- < 1) {
Changes to generic/tkImgPhInstance.c.
17
18
19
20
21
22
23




24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47

48
49
50
51
52
53
54
17
18
19
20
21
22
23
24
25
26
27
28
29
30

31



32




33
34
35
36
37

38
39
40
41
42
43

44
45
46
47
48
49
50
51







+
+
+
+



-
+
-
-
-

-
-
-
-





-
+





-
+







 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"
#include "tkPort.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * 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
#ifndef TK_CAN_RENDER_RGBA
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 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 int		ReclaimColors(ColorTableId *id, int numColors);

/*
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91







-
+







 *----------------------------------------------------------------------
 */

void
TkImgPhotoConfigureInstance(
    PhotoInstance *instancePtr)	/* Instance to reconfigure. */
{
    PhotoModel *modelPtr = instancePtr->modelPtr;
    PhotoModel *modelPtr = instancePtr->masterPtr;
    XImage *imagePtr;
    int bitsPerPixel;
    ColorTable *colorTablePtr;
    XRectangle validBox;

    /*
     * If the -palette configuration option has been set for the model, use
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+







	    || (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--;
	    colorTablePtr->liveRefCount -= 1;
	    FreeColorTable(colorTablePtr, 0);
	}
	GetColorTable(instancePtr);

	/*
	 * Create a new XImage structure for sending data to the X server, if
	 * necessary.
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227



228
229
230
231
232
233
234
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234







-
+







+
+
+







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;
    PhotoModel *modelPtr = 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;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
    int gcmask;
#endif

    /*
     * Table of "best" choices for palette for PseudoColor displays with
     * between 3 and 15 bits/pixel.
     */

    static const int paletteChoice[13][3] = {
253
254
255
256
257
258
259
260





261
262
263
264
265
266
267
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270
271







-
+
+
+
+
+







     * 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)) {
	    && (Tk_Display(tkwin) == instancePtr->display)
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
	    && (Tk_Visual(tkwin) == instancePtr->visualInfo.visual)
#endif
	    ) {
	    /*
	     * Re-use this instance.
	     */

	    if (instancePtr->refCount == 0) {
		/*
		 * We are resurrecting this instance.
279
280
281
282
283
284
285
286
287


288
289
290
291
292
293
294
283
284
285
286
287
288
289


290
291
292
293
294
295
296
297
298







-
-
+
+







    }

    /*
     * 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 = ckalloc(sizeof(PhotoInstance));
    instancePtr->masterPtr = 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;
310
311
312
313
314
315
316




317
318
319
320
321
322
323








324
325
326
327
328
329
330
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346







+
+
+
+







+
+
+
+
+
+
+
+







	Tcl_Panic("TkImgPhotoGet couldn't find visual for window");
    }

    nRed = 2;
    nGreen = nBlue = 0;
    mono = 1;
    instancePtr->visualInfo = *visInfoPtr;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
    gcmask = 0;
    instancePtr->visualInfo.visual = Tk_Visual(tkwin);
#endif
    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;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
	if (visInfoPtr->depth > 24) {
	    gcValues.plane_mask = visInfoPtr->red_mask
		    | visInfoPtr->green_mask
		    | visInfoPtr->blue_mask;
	    gcmask = GCPlaneMask;
	}
#endif
	break;
    case PseudoColor:
    case StaticColor:
	if (visInfoPtr->depth > 15) {
	    nRed = 32;
	    nGreen = 32;
	    nBlue = 32;
342
343
344
345
346
347
348
349

350
351

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368



369


370
371
372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
358
359
360
361
362
363
364

365
366

367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411







-
+

-
+
















+

+
+
+
-
+
+













-
+







    case StaticGray:
	nRed = 1 << visInfoPtr->depth;
	break;
    }
    XFree((char *) visInfoPtr);

    if (mono) {
	sprintf(buf, "%d", nRed);
	snprintf(buf, sizeof(buf), "%d", nRed);
    } else {
	sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue);
	snprintf(buf, sizeof(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;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
    instancePtr->gc = Tk_GetGC(tkwin,
	gcmask|GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
#else
    instancePtr->gc = Tk_GetGC(tkwin,
	    GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
	GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
#endif

    /*
     * 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,
	Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
    }

    return instancePtr;
}

/*
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447







-
+







 *	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 TK_CAN_RENDER_RGBA
#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) | \
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473







-
+







    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;
    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.
     *
495
496
497
498
499
500
501
502

503
504
505
506
507
508
509
516
517
518
519
520
521
522

523
524
525
526
527
528
529
530







-
+







    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;
	    line = (y + yOffset) * iPtr->masterPtr->width;
	    for (x = 0; x < width; x++) {
		modelPtr = alphaAr + ((line + x + xOffset) * 4);
		alpha = modelPtr[3];

		/*
		 * Ignore pixels that are fully transparent
		 */
538
539
540
541
542
543
544
545

546
547
548
549
550
551
552
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573







-
+







	    }
	}
	return;
    }
#endif /* !_WIN32 */

    for (y = 0; y < height; y++) {
	line = (y + yOffset) * iPtr->modelPtr->width;
	line = (y + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    modelPtr = alphaAr + ((line + x + xOffset) * 4);
	    alpha = modelPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613







-
+







		}
		XPutPixel(bgImg, x, y, RGB(r, g, b));
	    }
	}
    }
#undef ALPHA_BLEND
}
#endif /* TKPUTIMAGE_CAN_BLEND */
#endif /* TK_CAN_RENDER_RGBA */

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
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
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







-
-
+
+












-
+
+

-
+



-
+




-
+




+


-
+







    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
    PhotoInstance *instancePtr = clientData;
#ifndef TK_CAN_RENDER_RGBA
    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
#ifdef TK_CAN_RENDER_RGBA

    /*
     * If TkPutImage can handle RGBA Ximages directly there is
     * We can use TkpPutRGBAImage to render RGBA Ximages directly so there is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     */

    unsigned char *rgbaPixels = instancePtr->modelPtr->pix32;
    unsigned char *rgbaPixels = instancePtr->masterPtr->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,
    TkpPutRGBAImage(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)
    if ((instancePtr->masterPtr->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
682
683
684
685
686
687
688
689

690
691
692
693
694
695
696

697
698
699
700
701
702
703
705
706
707
708
709
710
711

712
713
714
715
716
717
718

719
720
721
722
723
724
725
726







-
+






-
+







	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
	 * modelPtr->validRegion 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);
		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);
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
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







-
+

-














-
+







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;
    PhotoInstance *instancePtr = 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--;
	colorPtr->liveRefCount -= 1;
    }

    Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr);
}

/*
 *----------------------------------------------------------------------
778
779
780
781
782
783
784
785

786
787
788
789
790
791
792
800
801
802
803
804
805
806

807
808
809
810
811
812
813
814







-
+







{
    PhotoModel *modelPtr;
    schar *newError, *errSrcPtr, *errDestPtr;
    int h, offset;
    XRectangle validBox;
    Pixmap newPixmap;

    modelPtr = instancePtr->modelPtr;
    modelPtr = instancePtr->masterPtr;
    TkClipBox(modelPtr->validRegion, &validBox);

    if ((instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)
	    || (instancePtr->pixels == None)) {
	newPixmap = Tk_GetPixmap(instancePtr->display,
		RootWindow(instancePtr->display,
828
829
830
831
832
833
834
835

836
837
838
839
840
841
842
850
851
852
853
854
855
856

857
858
859
860
861
862
863
864







-
+







	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
	    newError = 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.
	     */

866
867
868
869
870
871
872
873
874


875
876
877
878
879
880
881
888
889
890
891
892
893
894


895
896
897
898
899
900
901
902
903







-
-
+
+







	     * 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));
			(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;

995
996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
1031







-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CountBits(
    unsigned mask)			/* Value to count the 1 bits in. */
    pixel mask)			/* Value to count the 1 bits in. */
{
    int n;

    for (n=0 ; mask!=0 ; mask&=mask-1) {
	n++;
    }
    return n;
1057
1058
1059
1060
1061
1062
1063
1064

1065
1066
1067
1068
1069
1070

1071
1072
1073
1074
1075
1076
1077
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091

1092
1093
1094
1095
1096
1097
1098
1099







-
+





-
+







    entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew);

    if (!isNew) {
	/*
	 * Re-use the existing entry.
	 */

	colorPtr = (ColorTable *)Tcl_GetHashValue(entry);
	colorPtr = Tcl_GetHashValue(entry);
    } else {
	/*
	 * No color table currently available; need to make one.
	 */

	colorPtr = (ColorTable *)ckalloc(sizeof(ColorTable));
	colorPtr = 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
1127
1128
1129
1130
1131
1132
1133

1134

1135
1136
1137
1138
1139
1140
1141
1149
1150
1151
1152
1153
1154
1155
1156

1157
1158
1159
1160
1161
1162
1163
1164







+
-
+








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-- > 1) {
    if (colorPtr->refCount > 0) {
	return;
    }

    if (force) {
	if (colorPtr->flags & DISPOSE_PENDING) {
	    Tcl_CancelIdleCall(DisposeColorTable, colorPtr);
	    colorPtr->flags &= ~DISPOSE_PENDING;
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
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







-
+



















-
+







	     */

	    if (mono) {
		numColors = nGreen = nBlue = nRed;
	    } else {
		numColors = MAX(MAX(nRed, nGreen), nBlue);
	    }
	    colors = (XColor *)ckalloc(numColors * sizeof(XColor));
	    colors = 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));
	    colors = ckalloc(numColors * sizeof(XColor));

	    if (!mono) {
		/*
		 * Color display using a PseudoColor or StaticColor visual.
		 */

		i = 0;
1288
1289
1290
1291
1292
1293
1294
1295

1296
1297
1298
1299
1300
1301
1302
1311
1312
1313
1314
1315
1316
1317

1318
1319
1320
1321
1322
1323
1324
1325







-
+







	    }
	}

	/*
	 * Now try to allocate the colors we've calculated.
	 */

	pixels = (unsigned long *)ckalloc(numColors * sizeof(unsigned long));
	pixels = 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.
		 */
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
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







-
+











-
+







 */

static void
DisposeColorTable(
    ClientData clientData)	/* Pointer to the ColorTable whose
				 * colors are to be released. */
{
    ColorTable *colorPtr = (ColorTable *)clientData;
    ColorTable *colorPtr = 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);
    entry = Tcl_FindHashEntry(&imgPhotoColorHash, (char *) &colorPtr->id);
    if (entry == NULL) {
	Tcl_Panic("DisposeColorTable couldn't find hash entry");
    }
    Tcl_DeleteHashEntry(entry);

    ckfree(colorPtr);
}
1508
1509
1510
1511
1512
1513
1514
1515

1516
1517
1518
1519
1520
1521
1522
1531
1532
1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543
1544
1545







-
+







    /*
     * 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);
	colorPtr = 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.
1537
1538
1539
1540
1541
1542
1543
1544

1545
1546
1547
1548
1549
1550
1551
1560
1561
1562
1563
1564
1565
1566

1567
1568
1569
1570
1571
1572
1573
1574







-
+








    /*
     * Scan through a second time freeing colors.
     */

    entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
    while ((entry != NULL) && (numColors > 0)) {
	colorPtr = (ColorTable *)Tcl_GetHashValue(entry);
	colorPtr = 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.
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
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







-
+


















-
-
+
+

-
+







 */

void
TkImgDisposeInstance(
    ClientData clientData)	/* Pointer to the instance whose resources are
				 * to be released. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    PhotoInstance *instancePtr = 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;
    if (instancePtr->masterPtr->instancePtr == instancePtr) {
	instancePtr->masterPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->modelPtr->instancePtr;
	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(instancePtr);
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652

1653
1654
1655
1656
1657
1658
1659
1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671
1672
1673
1674

1675
1676
1677
1678
1679
1680
1681
1682







-
+






-
+







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;
    PhotoModel *modelPtr = 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;
    unsigned firstBit, word, mask;
    pixel 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)
1692
1693
1694
1695
1696
1697
1698
1699

1700
1701
1702
1703
1704
1705
1706
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
1729







-
+







    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);
    imagePtr->data = 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;
1718
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754
1755







-
+







	    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;
	    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.
1809
1810
1811
1812
1813
1814
1815
1816

1817
1818
1819
1820
1821
1822
1823
1832
1833
1834
1835
1836
1837
1838

1839
1840
1841
1842
1843
1844
1845
1846







-
+







			 * 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):
		    case NBBY * sizeof(pixel):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
1871
1872
1873
1874
1875
1876
1877
1878

1879
1880
1881
1882
1883
1884
1885
1894
1895
1896
1897
1898
1899
1900

1901
1902
1903
1904
1905
1906
1907
1908







-
+







			 * 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):
		    case NBBY * sizeof(pixel):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
1981
1982
1983
1984
1985
1986
1987
1988
1989


1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2004
2005
2006
2007
2008
2009
2010


2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022







-
-
+
+











void
TkImgResetDither(
    PhotoInstance *instancePtr)
{
    if (instancePtr->error) {
	memset(instancePtr->error, 0,
		(size_t) instancePtr->modelPtr->width
		* instancePtr->modelPtr->height * 3 * sizeof(schar));
	       /*(size_t)*/ (instancePtr->masterPtr->width
		* instancePtr->masterPtr->height * 3 * sizeof(schar)));
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkImgPhoto.c.
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72








73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113



114
115
116
117
118
119
120
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58

59
60
61









62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104



105
106
107
108
109
110
111
112
113
114







-








-



-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+







-








-



















-
-
-
+
+
+







/*
 * 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_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_WITHALPHA	0x200
#define OPT_ZOOM	0x400
#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[] = {
    "-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,
			    void **clientDataPtr);
static void		ImgPhotoDelete(void *clientData);
static int		ImgPhotoPostscript(void *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:
 */
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161


162
163



164
165

166
167

168
169

170
171

172
173
174
175
176
177
178
179
180


181
182
183
184
185
186

187
188
189
190
191
192



193
194
195
196
197
198
199
125
126
127
128
129
130
131

132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160

161
162

163
164

165
166

167
168
169
170
171
172
173
174


175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198







-



-



















+
+

-
+
+
+

-
+

-
+

-
+

-
+







-
-
+
+





-
+






+
+
+







    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, "-data", NULL, NULL,
	 NULL, -1, TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	 NULL, offsetof(PhotoModel, fileString), TK_CONFIG_NULL_OK, NULL},
	 NULL, Tk_Offset(PhotoModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-format", NULL, NULL,
	 NULL, -1, TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL,
	 DEF_PHOTO_GAMMA, offsetof(PhotoModel, gamma), 0, NULL},
	 DEF_PHOTO_GAMMA, Tk_Offset(PhotoModel, gamma), 0, NULL},
    {TK_CONFIG_INT, "-height", NULL, NULL,
	 DEF_PHOTO_HEIGHT, offsetof(PhotoModel, userHeight), 0, NULL},
	 DEF_PHOTO_HEIGHT, Tk_Offset(PhotoModel, userHeight), 0, NULL},
    {TK_CONFIG_UID, "-palette", NULL, NULL,
	 DEF_PHOTO_PALETTE, offsetof(PhotoModel, palette), 0, NULL},
	 DEF_PHOTO_PALETTE, Tk_Offset(PhotoModel, palette), 0, NULL},
    {TK_CONFIG_INT, "-width", NULL, NULL,
	 DEF_PHOTO_WIDTH, offsetof(PhotoModel, userWidth), 0, NULL},
	 DEF_PHOTO_WIDTH, Tk_Offset(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,
static void		PhotoFormatThreadExitProc(void *clientData);
static int		ImgPhotoCmd(void *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 void		ImgPhotoCmdDeletedProc(void *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 int		ImgStringWrite(Tcl_Interp *interp,
			    Tcl_Obj *formatString,
			    Tk_PhotoImageBlock *blockPtr);
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);
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
222
223
224
225
226
227
228

229
230
231
232
233

234
235
236
237
238
239
240







-





-







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);
    }
}
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301

302


303
304
305
306
307
308
309







-




















-


















-



-
+
-
-







 * 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
    } 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;
    }
341
342
343
344
345
346
347
348

349
350
351
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358







-
+










-
+







    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
    void **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->tkMaster = 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();
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417


418

419
420

421
422

423
424
425
426
427
428
429
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
424







-
+















-
+
+

+


+

-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCmd(
    ClientData clientData,	/* Information about photo model. */
    void *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;
    int result, x, y, width, height, dataWidth, dataHeight, listObjc;
    int index;
    struct SubcommandOptions options;
    Tcl_Obj **listObjv, **srcObjv;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    Tk_Window tkwin;
    Tk_PhotoImageFormat *imageFormat;
    TkSizeT length;
    int length;
    int imageWidth, imageHeight, matched, oldformat = 0;
    Tcl_Channel chan;
    Tk_PhotoHandle srcHandle;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
453
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
448
449
450
451
452
453
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







-
+
+










-
+













-
+








-
+






-
+







-
+

+

-
+








-
+




-
+








-
+







    case PHOTO_CGET: {
	const char *arg;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	arg = TkGetStringFromObj(objv[2], &length);
	arg = Tcl_GetString(objv[2]);
	length = 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);
		    (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);
		    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_AppendStringsToObj(subobj, " {}", (char *)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_AppendStringsToObj(subobj, " {}", (char *)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);
	    const char *arg = Tcl_GetString(objv[2]);

	    length = objv[2]->length;
	    if (length > 1 && !strncmp(arg, "-data", length)) {
		Tcl_AppendResult(interp, "-data {} {} {}", NULL);
		Tcl_AppendResult(interp, "-data {} {} {}", (char *)NULL);
		if (modelPtr->dataString) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->dataString);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		    Tcl_AppendResult(interp, " {}", (char *)NULL);
		}
		return TCL_OK;
	    } else if (length > 1 &&
		    !strncmp(arg, "-format", length)) {
		Tcl_AppendResult(interp, "-format {} {} {}", NULL);
		Tcl_AppendResult(interp, "-format {} {} {}", (char *)NULL);
		if (modelPtr->format) {
		    /*
		     * TODO: Modifying result is bad!
		     */

		    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp),
			    modelPtr->format);
		} else {
		    Tcl_AppendResult(interp, " {}", NULL);
		    Tcl_AppendResult(interp, " {}", (char *)NULL);
		}
		return TCL_OK;
	    } else {
		return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
			configSpecs, (char *) modelPtr, arg, 0);
	    }
	} else {
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
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







-
+



-
+


-
-
-



-
+








	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);
		    Tcl_GetString(options.name), (char *)NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetImage(srcHandle, &block);
	if ((options.fromX2 > block.width) || (options.fromY2 > block.height)
	if ((options.fromX > block.width) || (options.fromY > 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);
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * Hack to pass through the message that the place we're coming from
	 * has a simple alpha channel.
	 */
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
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







+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+











-
-
-


-
+



+
-
-
+
+
-
-




-
+
-







-
+










-
+

+
+
+








-
+
+
+
+











-
-
-
-





+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    options.toY2 = options.toY + height * options.zoomY;
	}

	/*
	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
	 */

	if (block.pixelPtr) {
	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);
	    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);
	} else {
	    result = TCL_OK;
	}

	/*
	 * 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);
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (block.pixelPtr || (options.options & OPT_SHRINK)) {
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
	    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
		    modelPtr->width, modelPtr->height);
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	return result;

    case PHOTO_DATA: {
        char *data = NULL;
	char *data;
        Tcl_Obj *freeObj = NULL;

	/*
	 * photo data command - first parse and check any options given.
	 */

	Tk_ImageStringWriteProc *stringWriteProc = NULL;

	index = 1;
	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)) {
	if ((options.name != NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    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);
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    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.
	 */

	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;
                }
	    }
	}
	    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;
                    }
                }
	    }
	}
	    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;
	    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);
		if (options.background) {
		    Tk_FreeColor(options.background);
		}
		return TCL_ERROR;
	    }
	} else {
	    stringWriteProc = ImgStringWrite;
	}

	/*
	 * Call the handler's string write function to write out the image.
	 */

	data = ImgGetPhoto(modelPtr, &block, &options);
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
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







-
+
-


-
+







-
-
-

-
-
-
-
-
-
-
-
-
-
-
-







-
+
-

-
-
-
-
-
-
-
-
-
+
+


-
-
-
-










-
+








-
-
-
+
+
+
-
-
+



-
+
-
-

-
+





-









+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
+
+

-
-
+
-
-
-
+
-
-
-
+
+
+
-
-
-
+
-
-
+
-
-
-
-
+
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+







	    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,
		    Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr);
		    void *dummy);

	    result = ((NewStringWriteProc)(void *)stringWriteProc)(interp,
		    options.format, &block, NULL);
		    options.format, &block);
	}
	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];
	Tcl_Obj *channels[3];
	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?");
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y");
	    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);
		    (char *)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[0] = Tcl_NewIntObj(pixelPtr[0]);
	channels[1] = Tcl_NewIntObj(pixelPtr[1]);
	channels[2] = Tcl_NewIntObj(pixelPtr[2]);
	channels[3] = Tcl_NewWideIntObj(pixelPtr[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels));
	Tcl_SetObjResult(interp, Tcl_NewListObj(3, channels));
	return TCL_OK;
    }

    case PHOTO_PUT: {
    case PHOTO_PUT:
	Tcl_Obj *format, *data;

	/*
	 * photo put command - first parse the options.
	 * photo put command - first parse the options and colors specified.
	 */

	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;
	}

	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) || (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,
		    imageWidth, imageHeight, 0, 0) != TCL_OK) {
		return TCL_ERROR;
	    }
	    modelPtr->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) {
	/*
	 * See if there's a format that can read the data
	 */
		    /*
		     * Lines must be non-empty...
		     */

		    break;
		}
		dataWidth = listObjc;
		/*
		 * Memory allocation overflow protection.
		 * May not be able to trigger/ demo / test this.
		 */

		if (dataWidth > (int)((UINT_MAX/3) / dataHeight)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"photo image dimensions exceed Tcl memory limits", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"OVERFLOW", NULL);
		    break;
		}
	if (MatchStringFormat(interp, objv[2], options.format, &imageFormat,
		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {
	    return TCL_ERROR;
	}

		pixelPtr = ckalloc(dataWidth * dataHeight * 3);
		block.pixelPtr = pixelPtr;
	    } else if (listObjc != dataWidth) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"all elements of color list must have the same"
			" number of elements", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NON_RECTANGULAR", NULL);
		break;
	    }

	    for (x = 0; x < dataWidth; ++x) {
		const 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_SetObjResult(interp, Tcl_ObjPrintf(
			    "can't parse color \"%s\"", colorString));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", 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(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 + imageWidth;
	    options.toY2 = options.toY + imageHeight;
	    options.toX2 = options.toX + dataWidth;
	    options.toY2 = options.toY + dataHeight;
	}
	if (imageWidth > options.toX2 - options.toX) {
	    imageWidth = options.toX2 - options.toX;
	block.width = dataWidth;
	}
	if (imageHeight > options.toY2 - options.toY) {
	    imageHeight = options.toY2 - options.toY;
	block.height = dataHeight;
	}
	format = options.format;
	data = objv[2];
	block.pitch = dataWidth * 3;
	block.pixelSize = 3;
	block.offset[0] = 0;
	if (oldformat) {
	    if (format) {
		format = (Tcl_Obj *) Tcl_GetString(format);
	block.offset[1] = 1;
	    }
	    data = (Tcl_Obj *) Tcl_GetString(data);
	block.offset[2] = 2;
	}

	if (imageFormat->stringReadProc(interp, data, format,
		(Tk_PhotoHandle) modelPtr, options.toX, options.toY,
	block.offset[3] = 0;
	result = Tk_PhotoPutBlock(interp, modelPtr, &block,
		options.toX, options.toY, options.toX2 - options.toX,
		options.toX2 - options.toX,
		options.toY2 - options.toY, 0, 0) != TCL_OK) {
		options.toY2 - options.toY,
	    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;
    }
		TK_PHOTO_COMPOSITE_SET);
	ckfree(block.pixelPtr);
	return result;

    case PHOTO_READ: {
	Tcl_Obj *format;

	/*
	 * photo read command - first parse the options specified.
	 */

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
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







-
+














-
-
-
-
-







	/*
	 * 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);
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * Open the image file and look for a handler for it.
	 */

	chan = Tcl_OpenFileChannel(interp,
		Tcl_GetString(options.name), "r", 0);
	if (chan == NULL) {
	    return TCL_ERROR;
	}
	if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
		!= TCL_OK) {
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}
	if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
		!= TCL_OK) {
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}

	if (MatchFileFormat(interp, chan,
		Tcl_GetString(options.name), options.format, &imageFormat,
		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {
997
998
999
1000
1001
1002
1003
1004

1005
1006
1007
1008
1009
1010
1011
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098







-
+








	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_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)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 {
1019
1020
1021
1022
1023
1024
1025
1026

1027
1028
1029
1030
1031
1032
1033
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120







-
+








	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_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
		Tcl_Close(NULL, chan);
		return TCL_ERROR;
	    }
	}

	/*
	 * Call the handler's file read function to read the data into the
1073
1074
1075
1076
1077
1078
1079
1080

1081
1082
1083
1084
1085
1086
1087
1160
1161
1162
1163
1164
1165
1166

1167
1168
1169
1170
1171
1172
1173
1174







-
+







	}

	if (y < modelPtr->height) {
	    /*
	     * Tell the core image code that part of the image has changed.
	     */

	    Tk_ImageChanged(modelPtr->tkModel, x, y,
	    Tk_ImageChanged(modelPtr->tkMaster, x, y,
		    (modelPtr->width - x), (modelPtr->height - y),
		    modelPtr->width, modelPtr->height);
	}
	return TCL_OK;

    case PHOTO_TRANS: {
	static const char *const photoTransOptions[] = {
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
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







-
-
-
-
-
-
-
-
+
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
+



-
-
-

-
-
+
+
-
-
-




-
+

-

-
-
-
-
-
-
+
+



-
+
-
-
-
+
-
-
-
-
+


-
-
-
-
-
-
-
-
-
-
-
-
-






-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





+
+
+
+
+
+
+
-
-
+
+
+
-
-
+

+
+
+
+
+
+
+

+
+
+
+
-
+

+

-






-
+







	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?");
	    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;
	    }

	    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);
			(char *)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]));

	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pixelPtr[3] == 0));
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixelPtr[3]));
	    }
	    return TCL_OK;
	}

	case PHOTO_TRANS_SET: {
	    int newVal, boolMode;
	    int transFlag;
	    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?");
	    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_GetIntFromObj(interp, objv[4], &y) != TCL_OK)
		return TCL_ERROR;
	    }

		    || (Tcl_GetBooleanFromObj(interp, objv[5],
	    index = 5;
	    memset(&options, 0, sizeof(options));
	    if (ParseSubcommandOptions(&options, interp,
		    OPT_ALPHA, &index, objc, objv) != TCL_OK) {
		    &transFlag) != 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);
			(char *)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;
	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;

	    if (transFlag) {
		/*
		 * Make pixel transparent.
		 */

	    modRegion = TkCreateRegion();
	    TkUnionRectWithRegion(&setBox, modRegion, modRegion);
		TkRegion clearRegion = TkCreateRegion();

		TkUnionRectWithRegion(&setBox, clearRegion, clearRegion);
	    if (pixelPtr[3]) {
		TkUnionRectWithRegion(&setBox, modelPtr->validRegion,
		TkSubtractRegion(modelPtr->validRegion, clearRegion,
			modelPtr->validRegion);
		TkDestroyRegion(clearRegion);

		/*
		 * Set the alpha value correctly.
		 */

		pixelPtr[3] = 0;
	    } else {
		/*
		 * Make pixel opaque.
		 */

		TkSubtractRegion(modelPtr->validRegion, modRegion,
		TkUnionRectWithRegion(&setBox, modelPtr->validRegion,
			modelPtr->validRegion);
		pixelPtr[3] = 255;
	    }
	    TkDestroyRegion(modRegion);

	    /*
	     * Inform the generic image code that the image
	     * has (potentially) changed.
	     */

	    Tk_ImageChanged(modelPtr->tkModel, x, y, 1, 1,
	    Tk_ImageChanged(modelPtr->tkMaster, x, y, 1, 1,
		    modelPtr->width, modelPtr->height);
	    modelPtr->flags &= ~IMAGE_CHANGED;
	    return TCL_OK;
	}

	}
	Tcl_Panic("unexpected fallthrough");
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
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







-
+


















+
+
+








-
+
+
+
+







	/*
	 * 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);
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)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 ...?");
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    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);
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    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]
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
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







-














-







			    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.
	     */

1385
1386
1387
1388
1389
1390
1391
1392




1393
1394
1395
1396
1397
1398
1399
1406
1407
1408
1409
1410
1411
1412

1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423







-
+
+
+
+







			"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);
		    fmtString, (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}

	/*
	 * Call the handler's file write function to write out the image.
	 */

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
1475
1476
1477
1478
1479
1480
1481

1482



1483
1484
1485
1486
1487

1488


1489
1490
1491
1492
1493
1494
1495







-
+
-
-
-





-
+
-
-







/*
 *----------------------------------------------------------------------
 *
 * 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
 *	-subsample, -format, -shrink, and -compositingrule.
 *	-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
 *	Fields in *optPtr get filled in.
 *	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,
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
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







-
-
-
+
+
+










-
+







    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;
    int index, length, argIndex;
    int c, bit, currentBit;
    int values[4], numValues, maxValues;
    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);
	expandedOption = option = Tcl_GetStringFromObj(objv[index], &length);
	if (option[0] != '-') {
	    if (optPtr->name == NULL) {
		optPtr->name = objv[index];
		continue;
	    }
	    break;
	}
1554
1555
1556
1557
1558
1559
1560
1561
1562


1563
1564
1565
1566
1567
1568
1569
1573
1574
1575
1576
1577
1578
1579


1580
1581
1582
1583
1584
1585
1586
1587
1588







-
-
+
+







	     * 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])));
	    optPtr->background = Tk_AllocColorFromObj(interp, Tk_MainWindow(interp),
		    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.
1586
1587
1588
1589
1590
1591
1592
1593

1594
1595
1596
1597
1598
1599
1600
1601
1605
1606
1607
1608
1609
1610
1611

1612

1613
1614
1615
1616
1617
1618
1619







-
+
-







	    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
	} else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) {
		|| 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;
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
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







-
+






-
+





-
+



















-
+







    /*
     * Exception generation.
     */

  oneValueRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires a value", expandedOption));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL);
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", (char *)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);
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", (char *)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);
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_VALUE", (char *)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);
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", (char *)NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureModel --
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
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







-
-
+
+



-

-
-
-
-
-
-
+
+
+
+
+


-

-



-
+


-
-
+
+


-

-



-
+







    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;
    int i, length;
    int 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)) {
    for (i = 0; i < objc; i++) {
	const char *arg = Tcl_GetStringFromObj(objv[i], &length);
	if ((length > 1) && (arg[0] == '-')) {
	    if ((arg[1] == 'd') &&
		    !strncmp(arg, "-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);
			    "MISSING_VALUE", (char *)NULL);
		    return TCL_ERROR;
		}
	    } else if ((args[j][1] == 'f') &&
		    !strncmp(args[j], "-format", length)) {
	    } else if ((arg[1] == 'f') &&
		    !strncmp(arg, "-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);
			    "MISSING_VALUE", (char *)NULL);
		    return TCL_ERROR;
		}
	    }
	}
    }

    /*
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
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







-
+
-


-














-
+

-
+







    oldGamma = modelPtr->gamma;

    /*
     * Process the configuration options specified.
     */

    if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
	    j, args, (char *) modelPtr, flags) != TCL_OK) {
	    objc, (const char **)objv, (char *) modelPtr, flags|TK_CONFIG_OBJS) != 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;
	int bytesize;

	(void) TkGetByteArrayFromObj(data, &bytesize);
	(void) Tcl_GetByteArrayFromObj(data, &bytesize);
	if (bytesize) {
	    Tcl_IncrRefCount(data);
	} else {
	    data = NULL;
	}
	if (modelPtr->dataString) {
	    Tcl_DecrRefCount(modelPtr->dataString);
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
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







-
+




















-
+








-
-
-
-
-
-
+
+











-
+







     * 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);
	Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)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);
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)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) ||
	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);
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	if (oldformat && tempformat) {
	    tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	}
	result = imageFormat->fileReadProc(interp, chan,
1973
1974
1975
1976
1977
1978
1979
1980

1981
1982
1983
1984
1985
1986
1987
1979
1980
1981
1982
1983
1984
1985

1986
1987
1988
1989
1990
1991
1992
1993







-
+







		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);
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	tempdata = modelPtr->dataString;
	if (oldformat) {
	    if (tempformat) {
		tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
2022
2023
2024
2025
2026
2027
2028
2029

2030
2031
2032
2033
2034
2035
2036
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2042







-
+







	TkImgPhotoConfigureInstance(instancePtr);
    }

    /*
     * Inform the generic image code that the image has (potentially) changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    modelPtr->flags &= ~IMAGE_CHANGED;

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
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
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
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;
    unsigned char *end;

    /*
     * Set the COMPLEX_ALPHA flag if we have an image with partially
     * transparent bits.
     */

    mPtr->flags &= ~COMPLEX_ALPHA;
    if (c == NULL) {
	return 0;
    }
    end = c + len;
    c += 3;			/* Start at first alpha byte. */
    for (; c < end; c += 4) {
	if (*c && *c != 255) {
     	    mPtr->flags |= COMPLEX_ALPHA;
	    mPtr->flags |= COMPLEX_ALPHA;
	    break;
	}
    }
    return (mPtr->flags & COMPLEX_ALPHA);
}

/*
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
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







-
+












-
+







 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoDelete(
    ClientData modelData)	/* Pointer to PhotoModel structure for image.
    void *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;
    modelPtr->tkMaster = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->pix32 != NULL) {
	ckfree(modelPtr->pix32);
    }
    if (modelPtr->validRegion != NULL) {
2164
2165
2166
2167
2168
2169
2170
2171

2172
2173
2174
2175
2176
2177
2178


2179
2180
2181
2182
2183
2184
2185
2171
2172
2173
2174
2175
2176
2177

2178
2179
2180
2181
2182
2183


2184
2185
2186
2187
2188
2189
2190
2191
2192







-
+





-
-
+
+







 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    ClientData clientData)	/* Pointer to PhotoModel structure for
    void *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));
    if (modelPtr->tkMaster != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkMaster));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoSetSize --
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
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







-
+


















-
-
+














-
+


















-







-
+





-
+







	    }
	    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);
			"NOT_FILE_FORMAT", (char *)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) {
    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);
			    "NOT_FILE_FORMAT", (char *)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);
		    formatString, (char *)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);
		    "UNRECOGNIZED_DATA", (char *)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
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







-
+















-
-
-
-
-
-
-
-
-
-











-
+



-
-
-
-
-
-
-
-
-
-








-















-
+













-
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+



-
+
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-




-
-
-
-
-
-







				 * 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;
    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) {
	/*
	 * 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);
			"NOT_DATA_FORMAT", (char *)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);
			    "NOT_DATA_FORMAT", (char *)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) {
	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);
		    formatString, (char *)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;
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "couldn't recognize image data", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		    "UNRECOGNIZED_DATA", (char *)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 --
2714
2715
2716
2717
2718
2719
2720
2721
2722


2723
2724
2725
2726
2727
2728
2729
2665
2666
2667
2668
2669
2670
2671


2672
2673
2674
2675
2676
2677
2678
2679
2680







-
-
+
+







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);
    void *clientData =
	    Tk_GetImageMasterData(interp, imageName, &typePtr);

    if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
	return NULL;
    }
    return clientData;
}

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
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







-
-
-
+
+
+



















-
+
















-
+







     *
     * 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) {
    if (modelPtr->pix32 && (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);
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)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);
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
3043
3044
3045
3046
3047
3048
3049
3050

3051
3052
3053
3054
3055
3056
3057
2994
2995
2996
2997
2998
2999
3000

3001
3002
3003
3004
3005
3006
3007
3008







-
+







    /*
     * Add this new block to the region which specifies which data is valid.
     */

    if (alphaOffset) {
	/*
	 * This block is grossly inefficient. For each row in the image, it
	 * finds each continguous string of nontransparent pixels, then marks
	 * finds each contiguous string of nontransparent pixels, then marks
	 * those areas as valid in the validRegion mask. This makes drawing
	 * very efficient, because of the way we use X: we just say, here's
	 * your mask, and here's your data. We need not worry about the
	 * current background color, etc. But this costs us a lot on the image
	 * setup. Still, image setup only happens once, whereas the drawing
	 * happens many times, so this might be the best way to go.
	 *
3145
3146
3147
3148
3149
3150
3151
3152

3153
3154
3155
3156
3157
3158
3159
3096
3097
3098
3099
3100
3101
3102

3103
3104
3105
3106
3107
3108
3109
3110







-
+








    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,
    Tk_ImageChanged(modelPtr->tkMaster, x, y, width, height,
	    modelPtr->width, modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
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
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







-
-
-
+
+
+



















-
+















-
+







     *
     * 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) {
    if (modelPtr->pix32 && (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);
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)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);
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
3382
3383
3384
3385
3386
3387
3388
3389

3390
3391
3392
3393
3394
3395
3396
3333
3334
3335
3336
3337
3338
3339

3340
3341
3342
3343
3344
3345
3346
3347







-
+








			if (!alphaOffset || (alpha == 255)) {
			    *destPtr++ = srcPtr[0];
			    *destPtr++ = srcPtr[greenOffset];
			    *destPtr++ = srcPtr[blueOffset];
			    *destPtr++ = 255;
			    continue;
 			}
			}

			if (compRule==TK_PHOTO_COMPOSITE_SET || !destPtr[3]) {
			    /*
			     * Either this is the SET rule (we overwrite
			     * whatever is there) or the destination is
			     * entirely blank. In both cases, we just set the
			     * destination to the source.
3501
3502
3503
3504
3505
3506
3507
3508

3509
3510
3511
3512
3513
3514
3515
3452
3453
3454
3455
3456
3457
3458

3459
3460
3461
3462
3463
3464
3465
3466







-
+








    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,
    Tk_ImageChanged(modelPtr->tkMaster, x, y, width, height, modelPtr->width,
	    modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
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
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







+
-
-
+
+
+









-
+







    modelPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */

    if (modelPtr->pix32) {
    memset(modelPtr->pix32, 0,
	    ((size_t)modelPtr->width * modelPtr->height * 4));
	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,
    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand --
3690
3691
3692
3693
3694
3695
3696
3697

3698
3699
3700
3701

3702
3703
3704
3705
3706
3707
3708
3643
3644
3645
3646
3647
3648
3649

3650
3651
3652
3653

3654
3655
3656
3657
3658
3659
3660
3661







-
+



-
+







    }
    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);
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0, modelPtr->width,
	Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
3765
3766
3767
3768
3769
3770
3771
3772

3773
3774
3775
3776

3777
3778
3779
3780
3781
3782
3783
3718
3719
3720
3721
3722
3723
3724

3725
3726
3727
3728

3729
3730
3731
3732
3733
3734
3735
3736







-
+



-
+







    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);
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	}
	return TCL_ERROR;
    }
    Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
	    modelPtr->width, modelPtr->height);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
3951
3952
3953
3954
3955
3956
3957
3958

3959
3960
3961
3962
3963
3964
3965
3904
3905
3906
3907
3908
3909
3910

3911
3912
3913
3914
3915
3916
3917
3918







-
+







			srcPtr += blockPtr->pixelSize;
			destPtr += newPixelSize;
		    }
		    srcPtr += blockPtr->pitch -
			    blockPtr->width * blockPtr->pixelSize;
		}
	    } else {
	 	int gray = (unsigned char) (((optPtr->background->red>>8) * 11
		int gray = (unsigned char) (((optPtr->background->red>>8) * 11
			+ (optPtr->background->green>>8) * 16
			+ (optPtr->background->blue>>8) * 5 + 16) >> 5);

		for (y = blockPtr->height; y > 0; y--) {
		    for (x = blockPtr->width; x > 0; x--) {
			destPtr[0] += ((255 - *srcPtr) *
				(gray-destPtr[0])) / 255;
3995
3996
3997
3998
3999
4000
4001



















































4002
4003
4004
4005
4006
4007
4008
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    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 greenOffset, blueOffset;
    Tcl_Obj *data;

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    data = Tcl_NewObj();
    if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
	int row, col;

	for (row=0; row<blockPtr->height; row++) {
	    Tcl_Obj *line = Tcl_NewObj();
	    unsigned char *pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0]
		    + row * blockPtr->pitch;

	    for (col=0; col<blockPtr->width; col++) {
		Tcl_AppendPrintfToObj(line, "%s#%02x%02x%02x",
			col ? " " : "", *pixelPtr,
			pixelPtr[greenOffset], pixelPtr[blueOffset]);
		pixelPtr += blockPtr->pixelSize;
	    }
	    Tcl_ListObjAppendElement(NULL, data, line);
	}
    }
    Tcl_SetObjResult(interp, data);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoGetImage --
 *
 *	This function is called to obtain image data from a photo image. This
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
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







-
+




















-
+







-
+







 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ImgPhotoPostscript(
    ClientData clientData,	/* Handle for the photo image. */
    void *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
 * 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.
 *
 *----------------------------------------------------------------------
 */
#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,
4119
4120
4121
4122
4123
4124
4125
4126

4127
4128
4129
4130
4131
4132
4133
4123
4124
4125
4126
4127
4128
4129

4130
4131
4132
4133
4134
4135
4136
4137







-
+








/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic,
 * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic
 *
 * Backward compatability functions for preserving the old behaviour (i.e.
 * 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
4176
4177
4178
4179
4180
4181
4182

4183
4184
4185
4186
4187
4188
4189
4190
4191







-









    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:
 */
Changes to generic/tkImgPhoto.h.
23
24
25
26
27
28
29
30

31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







52
53
54
55
56
57
58
23
24
25
26
27
28
29

30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65







-
+



-
+

















+
+
+
+
+
+
+







#include "tkUnixInt.h"
#endif

/*
 * Forward declarations of the structures we define.
 */

#define PhotoMaster PhotoModel
#define PhotoModel PhotoMaster
typedef struct ColorTableId	ColorTableId;
typedef struct ColorTable	ColorTable;
typedef struct PhotoInstance	PhotoInstance;
typedef struct PhotoModel	PhotoModel;
typedef struct PhotoMaster	PhotoMaster;

/*
 * 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

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98


99
100
101
102
103
104
105
106

107
108
109


110
111
112
113
114
115
116
90
91
92
93
94
95
96




97




98
99
100

101
102
103
104
105

106
107


108
109
110
111
112
113
114
115
116







-
-
-
-

-
-
-
-
+
+

-





-
+

-
-
+
+







 * 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
    int	refCount;		/* Number of instances using this map. */
    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 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. */
    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. */
};
137
138
139
140
141
142
143
144
145


146
147
148
149
150
151
152
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152







-
-
+
+







#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
struct PhotoMaster {
    Tk_ImageMaster tkMaster;	/* 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. */
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179







-
+







    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.
 * 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 .
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
192
193
194
195
196
197
198

199
200
201
202
203
204


205



206
207
208
209
210
211
212







-
+





-
-
+
-
-
-








/*
 * 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. */
    PhotoMaster *masterPtr;	/* 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. */
    int 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. */
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
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);
    data = 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;
Changes to generic/tkInt.decls.
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
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)
    CONST86 char *TkFindStateString(const TkStateMap *mapPtr, int numKey)
}
declare 23 {
    void TkFocusDeadWindow(TkWindow *winPtr)
}
declare 24 {
    int TkFocusFilterEvent(TkWindow *winPtr, XEvent *eventPtr)
}
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
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)
    CONST86 char *TkKeysymToString(KeySym keysym)
}
declare 47 {
    int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[])
}
declare 48 {
    double TkLineToPoint(double end1Ptr[], double end2Ptr[], double pointPtr[])
}
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298







-
+







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)
	    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)
}
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408

409
410
411

412
413
414

415
416
417

418
419
420
421

422
423
424
425


426
427
428
429
430
431
432
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404

405
406
407

408
409
410

411
412
413

414
415
416

417
418
419
420

421
422
423


424
425
426
427
428
429
430
431
432







-
+












-
+


-
+


-
+


-
+


-
+



-
+


-
-
+
+







    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)
    CONST86 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)
    int TkClipBox(TkRegion rgn, XRectangle *rect_return)
}
declare 114 {
    Region XCreateRegion(void)
    TkRegion TkCreateRegion(void)
}
declare 115 {
    int XDestroyRegion(Region rgn)
    int TkDestroyRegion(TkRegion rgn)
}
declare 116 {
    int XIntersectRegion(Region sra, Region srcb, Region dr_return)
    int TkIntersectRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return)
}
declare 117 {
    int XRectInRegion(Region rgn, int x, int y, unsigned int width,
    int TkRectInRegion(TkRegion rgn, int x, int y, unsigned int width,
	    unsigned int height)
}
declare 118 {
    int XSetRegion(Display *display, GC gc, Region rgn)
    int TkSetRegion(Display *display, GC gc, TkRegion rgn)
}
declare 119 {
    int XUnionRectWithRegion(XRectangle *rect,
	    Region src, Region dr_return)
    int TkUnionRectWithRegion(XRectangle *rect,
	    TkRegion src, TkRegion dr_return)
}
declare 121 aqua {
    Pixmap TkpCreateNativeBitmap(Display *display, const void *source)
}
declare 122 aqua {
    void TkpDefineNativeBitmaps(void)
}
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
448
449
450
451
452
453
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)
    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 {
    int XSubtractRegion(Region sra, Region srcb, Region dr_return)
    int TkSubtractRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return)
}
declare 146 {
    void TkStylePkgInit(TkMainInfo *mainPtr)
}
declare 147 {
    void TkStylePkgFree(TkMainInfo *mainPtr)
}
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548







-
+







}
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,
    int 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 {
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
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







-
+


-
-
+
+



-
+


-
-
+
+



-
+


-
-
+
+



-
+


-
-
+
+



-
+


-
-
+
+



-
+


-
-
+
+







	    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)
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 170 {
    const char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
    CONST86 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, TkSizeT offset)
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 172 {
    const char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
    CONST86 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, TkSizeT offset)
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 174 {
    const char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
    CONST86 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, TkSizeT offset)
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 176 {
    const char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
    CONST86 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, TkSizeT offset)
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 178 {
    const char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
    CONST86 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, TkSizeT offset)
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 180 {
    const char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr)
    CONST86 char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int 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)
638
639
640
641
642
643
644
645
646
647
648
649

650
651
652
653
654
655
656
638
639
640
641
642
643
644


645


646
647
648
649
650
651
652
653







-
-

-
-
+







# 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)
    void TkUnusedStubEntry(void)
}


##############################################################################

# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.
914
915
916
917
918
919
920
921
922
923


924

925
926
927
928
929
930
931
911
912
913
914
915
916
917



918
919

920
921
922
923
924
925
926
927







-
-
-
+
+
-
+







}
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 11 aqua {
    void TkMacOSXInstallCursor(int resizeOverride)
# }
}
declare 12 aqua {
    void TkMacOSXHandleTearoffMenu(void)
}
declare 14 aqua {
    int TkMacOSXDoHLEvent(void *theEvent)
}
declare 16 aqua {
989
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999







-
+







#declare 33 aqua {
#    void TkMacOSXUnregisterMacWindow(void *portPtr)
#}
declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    Region TkMacOSXVisableClipRgn(TkWindow *winPtr)
    TkRegion TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
    void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry)
}
declare 37 aqua {
    void TkMacOSXWindowOffset(void *wRef, int *xOffset, int *yOffset)
}
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033

1034
1035
1036
1037
1038
1039
1040
1019
1020
1021
1022
1023
1024
1025

1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036







-
+


-
+







declare 45 aqua {
    void TkMacOSXPreprocessMenu(void)
}
declare 46 aqua {
    int TkpIsWindowFloating(void *window)
}
declare 47 aqua {
    Tk_Window TkpGetCapture(void)
    Tk_Window TkMacOSXGetCapture(void)
}
declare 49 aqua {
    Tk_Window TkMacOSXGetContainer(TkWindow *winPtr)
    Tk_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)
}
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345



1346
1347

1348
1349
1350
1351
1352
1353
1354
1331
1332
1333
1334
1335
1336
1337




1338
1339
1340


1341
1342
1343
1344
1345
1346
1347
1348







-
-
-
-
+
+
+
-
-
+







	    KeySym *k, Status *s)
}
declare 80 win {
    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)
}
# This slot is reserved for use by the clipping rectangle patch:
#  declare 81 win {
#      XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
#  	    int clip_y_origin, XRectangle rectangles[], int n, int ordering)
declare 81 win {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
	    int clip_y_origin, XRectangle rectangles[], int n, int ordering)
#  }

}
declare 82 win {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 83 win {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
+



-
+

-
+



-
+


-
+




-
+



-
+


-
+


-
+


-
+


-
-
-
+
+

-
+


-
+


-
+


-
+


-
+


-
+



-
+



-
+



-
+



-
+




-
+



-
+


-
+


-
+



-
+


-
+



-
+



-
+



-
+


-
+


-
+



-
+


-
+




-
+




-
+


-
+



-
+


-
+


-
+



-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+




-
+



-
+



-
+


-
+



-
+


-
+


-
+


-
+



-
+



-
+


-
+


-
+


-
+


-
+


-
+


-
+


-
+



-
+


-
+


-
+



-
+



-
+



-
+



-
+


-
+



-
+



-
+


-
+


-
+



-
+




-
+


-
+



-
+



-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+



-
+


-
+


-
+


-
+


-
+


-
+


-
-
-
-
-
+


-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+


-
+



-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+


-
+
-
-
+





    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)
    void TkUnusedStubEntry(void)
}

################################
# X functions for MacOSX
# X functions for Aqua

declare 0 macosx {
declare 0 aqua {
    int XSetDashes(Display *display, GC gc, int dash_offset,
	    _Xconst char *dash_list, int n)
}
declare 1 macosx {
declare 1 aqua {
    XModifierKeymap *XGetModifierMapping(Display *d)
}
declare 2 macosx {
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 macosx {
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 macosx {
declare 4 aqua {
    char *XGetAtomName(Display *d, Atom a)
}
declare 5 macosx {
declare 5 aqua {
    char *XKeysymToString(KeySym k)
}
declare 6 macosx {
declare 6 aqua {
    Colormap XCreateColormap(Display *d, Window w, Visual *v, int i)
}
declare 7 macosx {
declare 7 aqua {
    GContext XGContextFromGC(GC g)
}
# second parameter was of type KeyCode
declare 8 macosx {
    KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i)
declare 8 aqua {
    KeySym XKeycodeToKeysym(Display *d, KeyCode k, int i)
}
declare 9 macosx {
declare 9 aqua {
    KeySym XStringToKeysym(_Xconst char *c)
}
declare 10 macosx {
declare 10 aqua {
    Window XRootWindow(Display *d, int i)
}
declare 11 macosx {
declare 11 aqua {
    XErrorHandler XSetErrorHandler(XErrorHandler x)
}
declare 12 macosx {
declare 12 aqua {
    Status XAllocColor(Display *d, Colormap c, XColor *xp)
}
declare 13 macosx {
declare 13 aqua {
    int XBell(Display *d, int i)
}
declare 14 macosx {
declare 14 aqua {
    int XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1,
	    int i2, _Xconst unsigned char *c, int i3)
}
declare 15 macosx {
declare 15 aqua {
    int XChangeWindowAttributes(Display *d, Window w, unsigned long ul,
	    XSetWindowAttributes *x)
}
declare 16 macosx {
declare 16 aqua {
    int XConfigureWindow(Display *d, Window w, unsigned int i,
	    XWindowChanges *x)
}
declare 17 macosx {
declare 17 aqua {
    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 {
declare 18 aqua {
    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 {
declare 19 aqua {
    Pixmap XCreateBitmapFromData(Display *display, Drawable d,
	    _Xconst char *data, unsigned int width, unsigned int height)
}
declare 20 macosx {
declare 20 aqua {
    int XDefineCursor(Display *d, Window w, Cursor c)
}
declare 21 macosx {
declare 21 aqua {
    int XDestroyWindow(Display *d, Window w)
}
declare 22 macosx {
declare 22 aqua {
    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 {
declare 23 aqua {
    int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)
}
declare 24 macosx {
declare 24 aqua {
    int XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 25 macosx {
declare 25 aqua {
    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 {
declare 26 aqua {
    int XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x,
	    int i1, int i2, int i3)
}
declare 27 macosx {
declare 27 aqua {
    int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i)
}
declare 28 macosx {
declare 28 aqua {
    int XFreeColormap(Display *d, Colormap c)
}
declare 29 macosx {
declare 29 aqua {
    int XFreeColors(Display *d, Colormap c,
	    unsigned long *ulp, int i, unsigned long ul)
}
declare 30 macosx {
declare 30 aqua {
    int XFreeModifiermap(XModifierKeymap *x)
}
declare 31 macosx {
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 macosx {
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 macosx {
declare 33 aqua {
    int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t)
}
declare 34 macosx {
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 macosx {
declare 35 aqua {
    KeyCode XKeysymToKeycode(Display *d, KeySym k)
}
declare 36 macosx {
declare 36 aqua {
    int XMapWindow(Display *d, Window w)
}
declare 37 macosx {
declare 37 aqua {
    int XMoveResizeWindow(Display *d, Window w, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 38 macosx {
declare 38 aqua {
    int XMoveWindow(Display *d, Window w, int i1, int i2)
}
declare 39 macosx {
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 macosx {
declare 40 aqua {
    int XRaiseWindow(Display *d, Window w)
}
declare 41 macosx {
declare 41 aqua {
    int XRefreshKeyboardMapping(XMappingEvent *x)
}
declare 42 macosx {
declare 42 aqua {
    int XResizeWindow(Display *d, Window w, unsigned int ui1,
	    unsigned int ui2)
}
declare 43 macosx {
declare 43 aqua {
    int XSelectInput(Display *d, Window w, long l)
}
declare 44 macosx {
declare 44 aqua {
    Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x)
}
declare 45 macosx {
declare 45 aqua {
    int XSetIconName(Display *d, Window w, _Xconst char *c)
}
declare 46 macosx {
declare 46 aqua {
    int XSetInputFocus(Display *d, Window w, int i, Time t)
}
declare 47 macosx {
declare 47 aqua {
    int XSetSelectionOwner(Display *d, Atom a, Window w, Time t)
}
declare 48 macosx {
declare 48 aqua {
    int XSetWindowBackground(Display *d, Window w, unsigned long ul)
}
declare 49 macosx {
declare 49 aqua {
    int XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p)
}
declare 50 macosx {
declare 50 aqua {
    int XSetWindowBorder(Display *d, Window w, unsigned long ul)
}
declare 51 macosx {
declare 51 aqua {
    int XSetWindowBorderPixmap(Display *d, Window w, Pixmap p)
}
declare 52 macosx {
declare 52 aqua {
    int XSetWindowBorderWidth(Display *d, Window w, unsigned int ui)
}
declare 53 macosx {
declare 53 aqua {
    int XSetWindowColormap(Display *d, Window w, Colormap c)
}
declare 54 macosx {
declare 54 aqua {
    int XUngrabKeyboard(Display *d, Time t)
}
declare 55 macosx {
declare 55 aqua {
    int XUngrabPointer(Display *d, Time t)
}
declare 56 macosx {
declare 56 aqua {
    int XUnmapWindow(Display *d, Window w)
}
declare 57 macosx {
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 macosx {
declare 58 aqua {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 59 macosx {
declare 59 aqua {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
}
declare 60 macosx {
declare 60 aqua {
    int XFreeGC(Display *display, GC gc)
}
declare 61 macosx {
declare 61 aqua {
    Atom XInternAtom(Display *display, _Xconst char *atom_name,
	    Bool only_if_exists)
}
declare 62 macosx {
declare 62 aqua {
    int XSetBackground(Display *display, GC gc, unsigned long foreground)
}
declare 63 macosx {
declare 63 aqua {
    int XSetForeground(Display *display, GC gc, unsigned long foreground)
}
declare 64 macosx {
declare 64 aqua {
    int XSetClipMask(Display *display, GC gc, Pixmap pixmap)
}
declare 65 macosx {
declare 65 aqua {
    int XSetClipOrigin(Display *display, GC gc,
	    int clip_x_origin, int clip_y_origin)
}
declare 66 macosx {
declare 66 aqua {
    int XSetTSOrigin(Display *display, GC gc,
	    int ts_x_origin, int ts_y_origin)
}
declare 67 macosx {
declare 67 aqua {
    int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values)
}
declare 68 macosx {
declare 68 aqua {
    int XSetFont(Display *display, GC gc, Font font)
}
declare 69 macosx {
declare 69 aqua {
    int XSetArcMode(Display *display, GC gc, int arc_mode)
}
declare 70 macosx {
declare 70 aqua {
    int XSetStipple(Display *display, GC gc, Pixmap stipple)
}
declare 71 macosx {
declare 71 aqua {
    int XSetFillRule(Display *display, GC gc, int fill_rule)
}
declare 72 macosx {
declare 72 aqua {
    int XSetFillStyle(Display *display, GC gc, int fill_style)
}
declare 73 macosx {
declare 73 aqua {
    int XSetFunction(Display *display, GC gc, int function)
}
declare 74 macosx {
declare 74 aqua {
    int XSetLineAttributes(Display *display, GC gc, unsigned int line_width,
	    int line_style, int cap_style, int join_style)
}
declare 75 macosx {
declare 75 aqua {
    int _XInitImageFuncPtrs(XImage *image)
}
declare 76 macosx {
declare 76 aqua {
    XIC XCreateIC(XIM xim, ...)
}
declare 77 macosx {
declare 77 aqua {
    XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask,
	    XVisualInfo *vinfo_template, int *nitems_return)
}
declare 78 macosx {
declare 78 aqua {
    void XSetWMClientMachine(Display *display, Window w,
	    XTextProperty *text_prop)
}
declare 79 macosx {
declare 79 aqua {
    Status XStringListToTextProperty(char **list, int count,
	    XTextProperty *text_prop_return)
}
declare 80 macosx {
declare 80 aqua {
    int XDrawSegments(Display *display, Drawable d, GC gc,
	    XSegment *segments, int nsegments)
}
declare 81 macosx {
declare 81 aqua {
    int XForceScreenSaver(Display *display, int mode)
}
declare 82 macosx {
declare 82 aqua {
    int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1,
	    int x2, int y2)
}
declare 83 macosx {
declare 83 aqua {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}
declare 84 macosx {
declare 84 aqua {
    int XClearWindow(Display *d, Window w)
}
declare 85 macosx {
declare 85 aqua {
    int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
}
declare 86 macosx {
declare 86 aqua {
    int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
	    int npoints, int mode)
}
declare 87 macosx {
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 macosx {
declare 88 aqua {
    int XQueryColor(Display *display, Colormap colormap, XColor *def_in_out)
}
declare 89 macosx {
declare 89 aqua {
    int XQueryColors(Display *display, Colormap colormap,
	    XColor *defs_in_out, int ncolors)
}
declare 90 macosx {
declare 90 aqua {
    Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3,
	    Window **w4, unsigned int *ui)
}
declare 91 macosx {
declare 91 aqua {
    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 {
declare 106 aqua {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
       int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
declare 107 macosx {
declare 107 aqua {
    int XFlush(Display *display)
}
declare 108 macosx {
declare 108 aqua {
    int XGrabServer(Display *display)
}
declare 109 macosx {
declare 109 aqua {
    int XUngrabServer(Display *display)
}
declare 110 macosx {
declare 110 aqua {
    int XFree(void *data)
}
declare 111 macosx {
declare 111 aqua {
    int XNoOp(Display *display)
}
declare 112 macosx {
declare 112 aqua {
    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 {
declare 114 aqua {
    VisualID XVisualIDFromVisual(Visual *visual)
}
declare 120 macosx {
    int XOffsetRegion(Region rgn, int dx, int dy)
declare 120 aqua {
    int XOffsetRegion(void *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 {
declare 129 aqua {
    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 {
declare 137 aqua {
    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 {
declare 144 aqua {
    void XDestroyIC(XIC xic)
}
declare 145 macosx {
declare 145 aqua {
    Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
	    XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2)
}
declare 146 macosx {
declare 146 aqua {
    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 {
declare 157 aqua {
    KeySym XkbKeycodeToKeysym(Display *d, unsigned int k, int g, int i)
}
declare 158 macosx {
declare 158 aqua {
    Display *XkbOpenDisplay(const char *name, int *ev_rtrn, int *err_rtrn,
	    int *major_rtrn, int *minor_rtrn, int *reason)
    void TkUnusedStubEntry(void)
}

# Local Variables:
# mode: tcl
# End:
Changes to generic/tkInt.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
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37








-
+












+
+






+







/*
 * tkInt.h --
 *
 *	Declarations for things used internally by the Tk functions but not
 *	exported outside the module.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998 by Scriptics Corporation.
 * Copyright (c) 1998 Scriptics Corporation.
 *
 * 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

#define TK_OPTION_ENUM_VAR		((int)(sizeof(Tk_OptionType)&(sizeof(int)-1))<<6)

/*
 * 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).
 */

#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
#    include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#    include <sys/param.h>
#endif
#ifdef BYTE_ORDER
69
70
71
72
73
74
75
76
77
78
79





80
81
82
83
84
85
86


87
88

89
90


91

92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113

114
115
116
117
118
119

120
121
122

123
124
125
126
127
128
129
72
73
74
75
76
77
78




79
80
81
82
83







84
85


86
87
88
89
90

91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112

113
114
115
116
117
118

119
120
121

122
123
124
125
126
127
128
129







-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
-
+


+
+
-
+





-
+












-
+


-
+





-
+


-
+







#   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
#if defined(_WIN32) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
# if TCL_UTF_MAX > 3
#   define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c)
#   define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c)
# 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_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
#endif

#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#   define TKFLEXARRAY
#if defined(__GNUC__) && (__GNUC__ > 2)
#elif defined(__GNUC__) && (__GNUC__ > 2)
#   define TKFLEXARRAY 0
#else
#   define TKFLEXARRAY 1
#endif

#if !defined(Tcl_GetParent) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
#ifndef Tcl_GetParent
#   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))
#	define PTR2INT(p) ((int)(intptr_t)(p))
#   else
#	define INT2PTR(p) ((void*)(p))
#	define PTR2INT(p) ((long)(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) ((uintptr_t)(p))
#	define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
#   else
#	define UINT2PTR(p) ((void*)(p))
#	define PTR2UINT(p) ((unsigned long)(p))
#	define PTR2UINT(p) ((unsigned int)(p))
#   endif
#endif

#ifndef TCL_Z_MODIFIER
#   if defined(_WIN64)
#	define TCL_Z_MODIFIER	"I"
#   elif defined(__GNUC__) && !defined(_WIN32)
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175







-
+














-
+








-
+







 * Opaque type declarations:
 */

typedef struct TkColormap TkColormap;
typedef struct TkFontAttributes TkFontAttributes;
typedef struct TkGrabEvent TkGrabEvent;
typedef struct TkpCursor_ *TkpCursor;
#define TkRegion Region
typedef struct TkRegion_ *TkRegion;
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
    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. */
    TkSizeT objRefCount;		/* Number of Tcl objects that reference this
    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
196
197
198
199
200
201
202


203
204
205
206
207
208
209







-
-








/*
 * 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. */
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251







-
+







				 * 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;
    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
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325







-
+







     * 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
    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:
     */
370
371
372
373
374
375
376






377
378


379
380
381
382
383
384
385
368
369
370
371
372
373
374
375
376
377
378
379
380


381
382
383
384
385
386
387
388
389







+
+
+
+
+
+
-
-
+
+








    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;

    /*
     * Information used by tkGrid.c, tkPack.c, tkPlace.c, tkPointer.c,
     * and ttkMacOSXTheme.c:
     */

#define TkGetContainer(tkwin) (Tk_TopWinHierarchy((TkWindow *)tkwin) ? NULL : \
#define TkGetContainer(tkwin) (((TkWindow *)tkwin)->maintainerPtr != NULL ? \
    ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr)
	(((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. */
448
449
450
451
452
453
454
455

456
457

458
459
460
461
462
463
464
452
453
454
455
456
457
458

459
460

461
462
463
464
465
466
467
468







-
+

-
+







				 * 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
    Tcl_HashTable masterTable;	/* Maps from Tk_Window toke to the Master
				 * structure for the window, if it exists. */
    Tcl_HashTable contentTable;	/* Maps from Tk_Window token to the Content
    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;
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
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







-
+






-
+








-
-




-
-
-
-
-

















+

-
-
-
-











+
+





+
+







    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)
#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. */

    TkSizeT refCount;		/* Reference count of how many Tk applications
    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
     */

#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. */
#ifdef TK_USE_INPUT_METHODS
    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.
 *  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
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







-
+










-
-
+
-
-
-







/*
 * 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
    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. */
#if TCL_MAJOR_VERSION > 8
    size_t deletionEpoch;		/* Incremented by window deletions. */
    long 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
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
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







+
+
+
+
+
+












-
+







    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. */
    Tcl_ObjCmdProc *tclUpdateObjProc;
				/* Saved Tcl [update] command, used to restore
				 * Tcl's version of [update] after Tk is shut
				 * down */
    unsigned int ttkNbTabsStickBit;
				/* Information used by ttk::notebook. */
} 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. */
				 * native style bitmap. */
} TkPredefBitmap;

/*
 * Tk keeps one of the following structures for each window. Some of the
 * information (like size and location) is a shadow of information managed by
 * the X server, and some is special information used here, such as event and
 * geometry management information. This information is (mostly) managed by
791
792
793
794
795
796
797
798

799
800
801
802
803
804
805
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)
#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):
     */
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
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







-
+







-
-
-
-


+
+
+
+
+
+
+











-
+





-
+














-
-
-
-
-
-
-
-
-







    /* 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)
#ifdef TK_USE_INPUT_METHODS
    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;

/*
 * String tables:
 */

MODULE_SCOPE const char *const tkStateStrings[];
MODULE_SCOPE const char *const tkCompoundStrings[];

/*
 * 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)
#elif !defined(MAC_OSX_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
    int 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;
958
959
960
961
962
963
964
965

966
967
968
969
970
971
972
952
953
954
955
956
957
958

959
960
961
962
963
964
965
966







-
+







 * 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;
	TkRegion region;
    } value;
} TkpClipMask;

#define TKP_CLIP_PIXMAP 0
#define TKP_CLIP_REGION 1

/*
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
1001
1002
1003
1004
1005
1006
1007

























1008
1009
1010
1011
1012
1013


1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
-
+
+

+







 * 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)
	(Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)


MODULE_SCOPE unsigned TkGetButtonMask(unsigned);

/*
 * 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;
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
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







-


-




















-
+







 * 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>
 * Support for Clang Static Analyzer <https://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
1122
1123
1124
1125
1126
1127
1128
1129

1130
1131
1132

1133
1134
1135
1136
1137
1138
1139
1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108







-
+



+







#include "tkIntDecls.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Themed widget set init function:
 * Themed widget set init function, and handler called when Tk is destroyed.
 */

MODULE_SCOPE int	Ttk_Init(Tcl_Interp *interp);
MODULE_SCOPE void	Ttk_TkDestroyedHandler(Tcl_Interp *interp);

/*
 * Internal functions shared among Tk modules but not exported to the outside
 * world:
 */

MODULE_SCOPE int	Tk_BellObjCmd(ClientData clientData,
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1218
1219
1220
1221
1222
1223
1224



1225
1226
1227
1228
1229
1230
1231







-
-
-







			    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,
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
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







+
+
+
+


+



-


-
+








-
-
-
-
-
-
-
-
-



-
+




-
+










+


















-
+
-
-









+
+
+
+







-
-
-

+



-
-
-
-
-
-








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+

+
+





+
-
-
-
+
+
+

+

-
-
+
+

-
-
+
-
-
-
-
-
-
-
-
-







			    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);
#define TkSetGeometryContainer TkSetGeometryMaster
MODULE_SCOPE int	TkSetGeometryContainer(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name);
#define TkFreeGeometryContainer TkFreeGeometryMaster
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[]);
			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
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);
			    void *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,
MODULE_SCOPE void	TkpBuildRegionFromAlphaData(TkRegion 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 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 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,
MODULE_SCOPE Tcl_Obj *	TkNewWindowObj(Tk_Window tkwin);
			    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 void	TkSendVirtualEvent(Tk_Window tgtWin,
			    const char *eventName, Tcl_Obj *detail);
MODULE_SCOPE void	TkDrawDottedRect(Display *disp, Drawable d, GC gc,
			    int x, int y, int width, int height);
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 void	TkpCancelWarp(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);
MODULE_SCOPE void	TkUnixSetXftClipRegion(TkRegion clipRegion);
#endif

MODULE_SCOPE void	TkpCopyRegion(TkRegion dst, TkRegion src);

#if !defined(__cplusplus) && !defined(c_plusplus)
# define c_class class
#endif

/* Tcl 8.6 has a different definition of Tcl_UniChar than other Tcl versions for TCL_UTF_MAX > 3 */
#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))
#if TCL_UTF_MAX > (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6))
#   define TkUtfToUniChar Tcl_UtfToUniChar
#   define TkUniCharToUtf Tcl_UniCharToUtf
#   define TkUtfPrev Tcl_UtfPrev
#   define TkUtfAtIndex Tcl_UtfAtIndex
#else
    MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
    MODULE_SCOPE int TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE int TkUniCharToUtf(int, char *);
    MODULE_SCOPE const char *TkUtfPrev(const char *, const char *);
#endif

    MODULE_SCOPE const char *TkUtfAtIndex(const char *src, int index);
#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,
Changes to generic/tkIntDecls.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
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17


18
19
20
21
22
23
24








-
+








-
-







/*
 * tkIntDecls.h --
 *
 *	This file contains the declarations for all unsupported
 *	functions that are exported by the Tk library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * 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.
 */

#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;
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114







-
+







				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,
EXTERN CONST86 char *	TkFindStateString(const TkStateMap *mapPtr,
				int numKey);
/* 23 */
EXTERN void		TkFocusDeadWindow(TkWindow *winPtr);
/* 24 */
EXTERN int		TkFocusFilterEvent(TkWindow *winPtr,
				XEvent *eventPtr);
/* 25 */
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







-
+







/* 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);
EXTERN CONST86 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 */
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264







-
+







				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);
				TkRegion damageRgn);
/* 80 */
EXTERN void		TkSelDeadWindow(TkWindow *winPtr);
/* 81 */
EXTERN void		TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);
/* 82 */
EXTERN void		TkSelInit(Tk_Window tkwin);
/* 83 */
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339

340
341

342
343

344
345
346


347
348

349
350
351

352
353
354


355
356
357
358
359
360
361
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336

337
338

339
340

341
342


343
344
345

346
347
348

349
350


351
352
353
354
355
356
357
358
359







-
+









-
+

-
+

-
+

-
-
+
+

-
+


-
+

-
-
+
+







/* 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,
EXTERN CONST86 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);
EXTERN int		TkClipBox(TkRegion rgn, XRectangle *rect_return);
/* 114 */
EXTERN Region		XCreateRegion(void);
EXTERN TkRegion		TkCreateRegion(void);
/* 115 */
EXTERN int		XDestroyRegion(Region rgn);
EXTERN int		TkDestroyRegion(TkRegion rgn);
/* 116 */
EXTERN int		XIntersectRegion(Region sra, Region srcb,
				Region dr_return);
EXTERN int		TkIntersectRegion(TkRegion sra, TkRegion srcb,
				TkRegion dr_return);
/* 117 */
EXTERN int		XRectInRegion(Region rgn, int x, int y,
EXTERN int		TkRectInRegion(TkRegion rgn, int x, int y,
				unsigned int width, unsigned int height);
/* 118 */
EXTERN int		XSetRegion(Display *display, GC gc, Region rgn);
EXTERN int		TkSetRegion(Display *display, GC gc, TkRegion rgn);
/* 119 */
EXTERN int		XUnionRectWithRegion(XRectangle *rect, Region src,
				Region dr_return);
EXTERN int		TkUnionRectWithRegion(XRectangle *rect, TkRegion src,
				TkRegion 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 */
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405
406


407
408
409
410
411
412
413
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400
401
402


403
404
405
406
407
408
409
410
411







-
+









-
-
+
+







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);
EXTERN TkRegion		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);
EXTERN int		TkSubtractRegion(TkRegion sra, TkRegion srcb,
				TkRegion 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);
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469







-
+







				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,
EXTERN int		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 */
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
482
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







-
+
-

-
-
-
+
+
+



-
+
-

-
-
-
+
+
+



-
+
-

-
-
-
+
+
+



-
+
-

-
-
-
+
+
+



-
+
-

-
-
-
+
+
+



-
+
-

-
-
-
+
+
+







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,
				const char *value, char *widgRec, int offset);
				TkSizeT offset);
/* 170 */
EXTERN const char *	TkStatePrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
EXTERN CONST86 char *	TkStatePrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 171 */
EXTERN int		TkCanvasDashParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				const char *value, char *widgRec, int offset);
				TkSizeT offset);
/* 172 */
EXTERN const char *	TkCanvasDashPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
EXTERN CONST86 char *	TkCanvasDashPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 173 */
EXTERN int		TkOffsetParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				const char *value, char *widgRec, int offset);
				TkSizeT offset);
/* 174 */
EXTERN const char *	TkOffsetPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
EXTERN CONST86 char *	TkOffsetPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 175 */
EXTERN int		TkPixelParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				const char *value, char *widgRec, int offset);
				TkSizeT offset);
/* 176 */
EXTERN const char *	TkPixelPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
EXTERN CONST86 char *	TkPixelPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 177 */
EXTERN int		TkOrientParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				const char *value, char *widgRec, int offset);
				TkSizeT offset);
/* 178 */
EXTERN const char *	TkOrientPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
EXTERN CONST86 char *	TkOrientPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 179 */
EXTERN int		TkSmoothParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec,
				const char *value, char *widgRec, int offset);
				TkSizeT offset);
/* 180 */
EXTERN const char *	TkSmoothPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec,
				TkSizeT offset, Tcl_FreeProc **freeProcPtr);
EXTERN CONST86 char *	TkSmoothPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int 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,
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578
579
555
556
557
558
559
560
561

562


563
564
565
566
567
568
569







-
+
-
-







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,
EXTERN void		TkUnusedStubEntry(void);
				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 */
593
594
595
596
597
598
599
600

601
602
603
604
605
606
607
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597







-
+







    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 */
    CONST86 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 */
617
618
619
620
621
622
623
624

625
626
627
628
629
630
631
607
608
609
610
611
612
613

614
615
616
617
618
619
620
621







-
+







    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 */
    CONST86 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 */
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
640
641
642
643
644
645
646

647
648
649
650
651
652
653
654







-
+







    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 */
    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);
    void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, const char *oldMenuName, const char *menuName); /* 85 */
    KeySym (*tkStringToKeysym) (const char *name); /* 86 */
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
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







-
+



-
-
-
-
-
-
-
+
+
+
+
+
+
+








+

+









+

+










+

+

















-
+




-
+

















-
+





-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+







    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 */
    CONST86 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 */
    int (*tkClipBox) (TkRegion rgn, XRectangle *rect_return); /* 113 */
    TkRegion (*tkCreateRegion) (void); /* 114 */
    int (*tkDestroyRegion) (TkRegion rgn); /* 115 */
    int (*tkIntersectRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 116 */
    int (*tkRectInRegion) (TkRegion rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */
    int (*tkSetRegion) (Display *display, GC gc, TkRegion rgn); /* 118 */
    int (*tkUnionRectWithRegion) (XRectangle *rect, TkRegion src, TkRegion 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 */
# if TCL_MAJOR_VERSION < 9
    void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    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 */
# if TCL_MAJOR_VERSION < 9
    void (*reserved122)(void); /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    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 */
# if TCL_MAJOR_VERSION < 9
    void (*reserved124)(void); /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    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 */
    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 */
    int (*xSubtractRegion) (Region sra, Region srcb, Region dr_return); /* 145 */
    int (*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)(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 */
    int (*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 */
    int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 169 */
    CONST86 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 */
    CONST86 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 */
    CONST86 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 */
    CONST86 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 */
    CONST86 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 */
    CONST86 char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int 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 */
801
802
803
804
805
806
807
808

809
810
811
812
813
814
815
797
798
799
800
801
802
803

804
805
806
807
808
809
810
811







-
+







#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 */
    void (*tkUnusedStubEntry) (void); /* 187 */
} TkIntStubs;

extern const TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}
#endif
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	(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 */
#define TkClipBox \
	(tkIntStubsPtr->tkClipBox) /* 113 */
#define TkCreateRegion \
	(tkIntStubsPtr->tkCreateRegion) /* 114 */
#define TkDestroyRegion \
	(tkIntStubsPtr->tkDestroyRegion) /* 115 */
#define TkIntersectRegion \
	(tkIntStubsPtr->tkIntersectRegion) /* 116 */
#define TkRectInRegion \
	(tkIntStubsPtr->tkRectInRegion) /* 117 */
#define TkSetRegion \
	(tkIntStubsPtr->tkSetRegion) /* 118 */
#define TkUnionRectWithRegion \
	(tkIntStubsPtr->tkUnionRectWithRegion) /* 119 */
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
#define TkpCreateNativeBitmap \
	(tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
#define TkpDefineNativeBitmaps \
1095
1096
1097
1098
1099
1100
1101
1102
1103


1104
1105
1106
1107
1108
1109
1110
1091
1092
1093
1094
1095
1096
1097


1098
1099
1100
1101
1102
1103
1104
1105
1106







-
-
+
+







	(tkIntStubsPtr->tkWmStackorderToplevel) /* 141 */
#define TkFocusFree \
	(tkIntStubsPtr->tkFocusFree) /* 142 */
#define TkClipCleanup \
	(tkIntStubsPtr->tkClipCleanup) /* 143 */
#define TkGCCleanup \
	(tkIntStubsPtr->tkGCCleanup) /* 144 */
#define XSubtractRegion \
	(tkIntStubsPtr->xSubtractRegion) /* 145 */
#define TkSubtractRegion \
	(tkIntStubsPtr->tkSubtractRegion) /* 145 */
#define TkStylePkgInit \
	(tkIntStubsPtr->tkStylePkgInit) /* 146 */
#define TkStylePkgFree \
	(tkIntStubsPtr->tkStylePkgFree) /* 147 */
#define TkToplevelWindowForCommand \
	(tkIntStubsPtr->tkToplevelWindowForCommand) /* 148 */
#define TkGetOptionSpec \
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

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







-
-
+
+








+
+
+
+
+
+
+
+
+
+
+
+
+








+
+
+
+
+
+
+
+
+
+
+
+
+
+








+
+

+
#define TkpRedrawWidget \
	(tkIntStubsPtr->tkpRedrawWidget) /* 185 */
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpWillDrawWidget \
	(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */
#endif /* MACOSX */
#define TkDebugPhotoStringMatchDef \
	(tkIntStubsPtr->tkDebugPhotoStringMatchDef) /* 187 */
#define TkUnusedStubEntry \
	(tkIntStubsPtr->tkUnusedStubEntry) /* 187 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

/*
 * On X11, these macros are just wrappers for the equivalent X Region calls.
 */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */

#undef TkClipBox
#undef TkCreateRegion
#undef TkDestroyRegion
#undef TkIntersectRegion
#undef TkRectInRegion
#undef TkSetRegion
#undef TkSubtractRegion
#undef TkUnionRectWithRegion
#undef TkpCmapStressed_
#undef TkpSync_
#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_

#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 /* UNIX */

#if !defined(MAC_OSX_TK)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget
#   define TkpWillDrawWidget(w) 0
#   define TkpRedrawWidget(w)
#endif

#undef TkUnusedStubEntry

#endif /* _TKINTDECLS */

Changes to generic/tkIntPlatDecls.h.
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16








-
+







/*
 * tkIntPlatDecls.h --
 *
 *	This file contains the declarations for all platform dependent
 *	unsupported functions that are exported by the Tk library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 * All rights reserved.
 */

#ifndef _TKINTPLATDECLS
#define _TKINTPLATDECLS

#ifdef BUILD_tk
166
167
168
169
170
171
172
173


174
175
176
177
178
179
180
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181







-
+
+







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 */
/* 11 */
EXTERN void		TkMacOSXInstallCursor(int resizeOverride);
/* 12 */
EXTERN void		TkMacOSXHandleTearoffMenu(void);
/* Slot 13 is reserved */
/* 14 */
EXTERN int		TkMacOSXDoHLEvent(void *theEvent);
/* Slot 15 is reserved */
/* 16 */
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226







-
+







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);
EXTERN TkRegion		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);
237
238
239
240
241
242
243
244

245
246
247

248
249
250
251
252
253
254
238
239
240
241
242
243
244

245
246
247

248
249
250
251
252
253
254
255







-
+


-
+







/* 44 */
EXTERN MacDrawable *	TkMacOSXGetHostToplevel(TkWindow *winPtr);
/* 45 */
EXTERN void		TkMacOSXPreprocessMenu(void);
/* 46 */
EXTERN int		TkpIsWindowFloating(void *window);
/* 47 */
EXTERN Tk_Window	TkpGetCapture(void);
EXTERN Tk_Window	TkMacOSXGetCapture(void);
/* Slot 48 is reserved */
/* 49 */
EXTERN Tk_Window	TkMacOSXGetContainer(TkWindow *winPtr);
EXTERN Tk_Window	TkGetTransientMaster(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);
397
398
399
400
401
402
403
404

405
406
407
408
409
410
411
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412







-
+







    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 (*tkMacOSXInstallCursor) (int resizeOverride); /* 11 */
    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 */
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440

441
442

443
444
445
446
447
448
449
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436
437
438
439
440

441
442

443
444
445
446
447
448
449
450







-
+











-
+

-
+







    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 */
    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 (*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 */
    Tk_Window (*tkMacOSXGetCapture) (void); /* 47 */
    void (*reserved48)(void);
    Tk_Window (*tkMacOSXGetContainer) (TkWindow *winPtr); /* 49 */
    Tk_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 */
623
624
625
626
627
628
629
630


631
632
633
634
635
636
637
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639







-
+
+







	(tkIntPlatStubsPtr->tkAboutDlg) /* 7 */
#define TkMacOSXButtonKeyState \
	(tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */
#define TkMacOSXClearMenubarActive \
	(tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */
#define TkMacOSXDispatchMenuEvent \
	(tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */
/* Slot 11 is reserved */
#define TkMacOSXInstallCursor \
	(tkIntPlatStubsPtr->tkMacOSXInstallCursor) /* 11 */
#define TkMacOSXHandleTearoffMenu \
	(tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */
/* Slot 13 is reserved */
#define TkMacOSXDoHLEvent \
	(tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */
/* Slot 15 is reserved */
#define TkMacOSXGetXWindow \
687
688
689
690
691
692
693
694
695


696
697
698


699
700
701
702
703
704
705
689
690
691
692
693
694
695


696
697
698


699
700
701
702
703
704
705
706
707







-
-
+
+

-
-
+
+







	(tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */
#define TkMacOSXGetHostToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGetHostToplevel) /* 44 */
#define TkMacOSXPreprocessMenu \
	(tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */
#define TkpIsWindowFloating \
	(tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */
#define TkpGetCapture \
	(tkIntPlatStubsPtr->tkpGetCapture) /* 47 */
#define TkMacOSXGetCapture \
	(tkIntPlatStubsPtr->tkMacOSXGetCapture) /* 47 */
/* Slot 48 is reserved */
#define TkMacOSXGetContainer \
	(tkIntPlatStubsPtr->tkMacOSXGetContainer) /* 49 */
#define TkGetTransientMaster \
	(tkIntPlatStubsPtr->tkGetTransientMaster) /* 49 */
#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */
#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */
#define TkpGetMS \
787
788
789
790
791
792
793


794


795
796
797
798
799
800
801
802
789
790
791
792
793
794
795
796
797

798
799
800
801
802
803



804







+
+
-
+
+




-
-
-

#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_
#undef TkGenerateActivateEvents_

#define TkMacOSXGetContainer TkGetTransientMaster
#undef TkMacOSXSetUpClippingRgn
#undef TkMacOSXIsCharacterMissing
#define TkMacOSXIsCharacterMissing(tkfont) ((void)tkfont, 0)

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkWinGetPlatformId
#define TkWinGetPlatformId() (2) /* VER_PLATFORM_WIN32_NT */

#endif /* _TKINTPLATDECLS */
Changes to generic/tkIntXlibDecls.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
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


26
27
28


29
30
31
32
33
34


35
36








37
38
39
40
41
42
43








-
+
















-
-
+
+
+
-
-
+

+
+


-
-
+
+
-
-
-
-
-
-
-
-







/*
 * tkIntXlibDecls.h --
 *
 *	This file contains the declarations for all platform dependent
 *	unsupported functions that are exported by the Tk library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 * All rights reserved.
 */

#ifndef _TKINTXLIBDECLS
#define _TKINTXLIBDECLS

/*
 * 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
/* Some (older) versions of X11/Xutil.h have a wrong signature of those
   two functions, so move them out of the way temporarily. */
#define XOffsetRegion _XOffsetRegion
#endif

#define XUnionRegion _XUnionRegion
#include "X11/Xutil.h"
#undef XOffsetRegion
#undef XUnionRegion

#ifdef BUILD_tk
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#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. */
277
278
279
280
281
282
283
284




285
286
287
288
289
290
291
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288







-
+
+
+
+







				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 */
/* 81 */
EXTERN int		XSetClipRectangles(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin,
				XRectangle rectangles[], int n, int ordering);
/* 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 */
415
416
417
418
419
420
421
422

423
424

425
426

427
428

429
430

431
432

433
434
435
436
437

438
439

440
441

442
443
444
445
446

447
448
449
450
451

452
453

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
412
413
414
415
416
417
418

419


420


421


422


423


424

425
426
427

428


429


430





431





432


433



434


435


436






437


438


439

440


441

442
443
444
445
446
447
448
449







-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-



-
+
-
-
+
-
-
+
-
-
-
-
-
+
-
-
-
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
-
-
-
-
+
-
-
+
-
-

-
+
-
-

-
+







/* 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 */
/* Slot 138 is reserved */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
/* Slot 139 is reserved */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
/* Slot 140 is reserved */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
/* Slot 141 is reserved */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
/* Slot 142 is reserved */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
/* Slot 143 is reserved */
EXTERN void		XSetICFocus(XIC xic);
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
/* 147 */
/* Slot 147 is reserved */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
/* Slot 148 is reserved */
EXTERN int		XCloseIM(XIM im);
/* 149 */
/* Slot 149 is reserved */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 150 */
/* Slot 150 is reserved */
EXTERN Bool		XUnregisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 151 */
/* Slot 151 is reserved */
EXTERN char *		XSetLocaleModifiers(const char *modifier_list);
/* 152 */
/* Slot 152 is reserved */
EXTERN XIM		XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb,
				char *res_name, char *res_class);
/* 153 */
/* Slot 153 is reserved */
EXTERN char *		XGetIMValues(XIM im, ...);
/* 154 */
/* Slot 154 is reserved */
EXTERN char *		XSetIMValues(XIM im, ...);
/* 155 */
/* Slot 155 is reserved */
EXTERN XFontSet		XCreateFontSet(Display *display,
				_Xconst char *base_font_name_list,
				char ***missing_charset_list,
				int *missing_charset_count,
				char **def_string);
/* 156 */
/* Slot 156 is reserved */
EXTERN void		XFreeStringList(char **list);
/* 157 */
/* Slot 157 is reserved */
EXTERN KeySym		XkbKeycodeToKeysym(Display *d, unsigned int k, int g,
				int i);
/* 158 */
EXTERN Display *	XkbOpenDisplay(const char *name, int *ev_rtrn,
EXTERN void		TkUnusedStubEntry(void);
				int *err_rtrn, int *major_rtrn,
				int *minor_rtrn, int *reason);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#ifdef MAC_OSX_TK /* AQUA */
/* 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,
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473







-
+







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);
EXTERN KeySym		XKeycodeToKeysym(Display *d, KeyCode 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 */
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
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







-
+
-
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
-
-
-
+
-
-
+
-
-
+
-
















-
+
-
-








-
-
+
+
-
-
-
+
-
-
-
-
-
-
-








-
+
-
-
-
+
-
-
-
+
-
-



-
+
-
-




-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-










-
+
-
-
+
-
-
+
-
-
-
-
-
+
-
-
-
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
-
-
-
-
+
-




-
+
-
-
-
+







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 */
/* Slot 92 is reserved */
EXTERN Bool		XTranslateCoordinates(Display *d, Window w1,
				Window w2, int i1, int i2, int *i3, int *i4,
				Window *w3);
/* 93 */
/* Slot 93 is reserved */
EXTERN int		XDeleteProperty(Display *d, Window w, Atom a);
/* 94 */
/* Slot 94 is reserved */
EXTERN int		XFreeCursor(Display *d, Cursor c);
/* 95 */
/* Slot 95 is reserved */
EXTERN int		XGetInputFocus(Display *d, Window *w, int *i);
/* 96 */
/* Slot 96 is reserved */
EXTERN int		XmbLookupString(XIC xi, XKeyPressedEvent *xk,
				char *c, int i, KeySym *k, Status *s);
/* 97 */
/* Slot 97 is reserved */
EXTERN int		XNextEvent(Display *d, XEvent *x);
/* 98 */
/* Slot 98 is reserved */
EXTERN int		XPutBackEvent(Display *d, XEvent *x);
/* 99 */
/* Slot 99 is reserved */
EXTERN int		XSetCommand(Display *d, Window w, char **c, int i);
/* 100 */
/* Slot 100 is reserved */
EXTERN int		XWindowEvent(Display *d, Window w, long l, XEvent *x);
/* 101 */
/* Slot 101 is reserved */
EXTERN Status		XGetWindowAttributes(Display *d, Window w,
				XWindowAttributes *x);
/* 102 */
/* Slot 102 is reserved */
EXTERN Status		XGetWMColormapWindows(Display *d, Window w,
				Window **wpp, int *ip);
/* 103 */
/* Slot 103 is reserved */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);
/* 104 */
/* Slot 104 is reserved */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);
/* 105 */
/* Slot 105 is reserved */
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 */
/* Slot 113 is reserved */
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		XOffsetRegion(void *rgn, int dx, int dy);
/* Slot 121 is reserved */
EXTERN int		XUnionRegion(Region srca, Region srcb,
				Region dr_return);
/* 122 */
/* Slot 122 is reserved */
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 */
/* Slot 130 is reserved */
EXTERN int		XFillArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 131 */
/* Slot 131 is reserved */
EXTERN int		XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 132 */
/* Slot 132 is reserved */
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 */
/* Slot 136 is reserved */
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 */
/* Slot 138 is reserved */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
/* Slot 139 is reserved */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
/* Slot 140 is reserved */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
/* Slot 141 is reserved */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
/* Slot 142 is reserved */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
/* Slot 143 is reserved */
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 */
/* Slot 147 is reserved */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
/* Slot 148 is reserved */
EXTERN int		XCloseIM(XIM im);
/* 149 */
/* Slot 149 is reserved */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 150 */
/* Slot 150 is reserved */
EXTERN Bool		XUnregisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 151 */
/* Slot 151 is reserved */
EXTERN char *		XSetLocaleModifiers(const char *modifier_list);
/* 152 */
/* Slot 152 is reserved */
EXTERN XIM		XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb,
				char *res_name, char *res_class);
/* 153 */
/* Slot 153 is reserved */
EXTERN char *		XGetIMValues(XIM im, ...);
/* 154 */
/* Slot 154 is reserved */
EXTERN char *		XSetIMValues(XIM im, ...);
/* 155 */
/* Slot 155 is reserved */
EXTERN XFontSet		XCreateFontSet(Display *display,
				_Xconst char *base_font_name_list,
				char ***missing_charset_list,
				int *missing_charset_count,
				char **def_string);
/* 156 */
/* Slot 156 is reserved */
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,
EXTERN void		TkUnusedStubEntry(void);
				int *err_rtrn, int *major_rtrn,
				int *minor_rtrn, int *reason);
#endif /* MACOSX */
#endif /* AQUA */

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 */
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993
878
879
880
881
882
883
884

885
886
887
888
889
890
891
892







-
+







    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);
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 81 */
    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 */
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
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







-
-
-
-
-
-
+
+
+
+
+
+



-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

-
+








-
+







    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 (*reserved138)(void);
    void (*reserved139)(void);
    void (*reserved140)(void);
    void (*reserved141)(void);
    void (*reserved142)(void);
    void (*reserved143)(void);
    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 */
    void (*reserved147)(void);
    void (*reserved148)(void);
    void (*reserved149)(void);
    void (*reserved150)(void);
    void (*reserved151)(void);
    void (*reserved152)(void);
    void (*reserved153)(void);
    void (*reserved154)(void);
    void (*reserved155)(void);
    void (*reserved156)(void);
    void (*reserved157)(void);
    void (*tkUnusedStubEntry) (void); /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#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, unsigned int k, int i); /* 8 */
    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 */
    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 */
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+







-
+






-
-
-
+
+
+







-
-
-
+
+
+



-
+

-
-
-
-
-
-
+
+
+
+
+
+



-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
+
+







    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 */
    void (*reserved92)(void);
    void (*reserved93)(void);
    void (*reserved94)(void);
    void (*reserved95)(void);
    void (*reserved96)(void);
    void (*reserved97)(void);
    void (*reserved98)(void);
    void (*reserved99)(void);
    void (*reserved100)(void);
    void (*reserved101)(void);
    void (*reserved102)(void);
    void (*reserved103)(void);
    void (*reserved104)(void);
    void (*reserved105)(void);
    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 */
    void (*reserved113)(void);
    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 */
    int (*xOffsetRegion) (void *rgn, int dx, int dy); /* 120 */
    void (*reserved121)(void);
    void (*reserved122)(void);
    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 (*reserved130)(void);
    void (*reserved131)(void);
    void (*reserved132)(void);
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*reserved135)(void);
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    void (*reserved136)(void);
    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 (*reserved138)(void);
    void (*reserved139)(void);
    void (*reserved140)(void);
    void (*reserved141)(void);
    void (*reserved142)(void);
    void (*reserved143)(void);
    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 */
    void (*reserved147)(void);
    void (*reserved148)(void);
    void (*reserved149)(void);
    void (*reserved150)(void);
    void (*reserved151)(void);
    void (*reserved152)(void);
    void (*reserved153)(void);
    void (*reserved154)(void);
    void (*reserved155)(void);
    void (*reserved156)(void);
    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 */
    void (*tkUnusedStubEntry) (void); /* 158 */
#endif /* AQUA */
} TkIntXlibStubs;

extern const TkIntXlibStubs *tkIntXlibStubsPtr;

#ifdef __cplusplus
}
#endif
1396
1397
1398
1399
1400
1401
1402
1403


1404
1405
1406
1407
1408
1409
1410
1295
1296
1297
1298
1299
1300
1301

1302
1303
1304
1305
1306
1307
1308
1309
1310







-
+
+







	(tkIntXlibStubsPtr->xDestroyIC) /* 77 */
#define XFilterEvent \
	(tkIntXlibStubsPtr->xFilterEvent) /* 78 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 79 */
#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 80 */
/* Slot 81 is reserved */
#define XSetClipRectangles \
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 81 */
#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 82 */
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 83 */
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 84 */
#define XInternAtom \
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
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







-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+



-
-
+
-
-
+
-
-
-
-
-
-
+
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
-
+
+
+

-
+







	(tkIntXlibStubsPtr->xDrawPoint) /* 134 */
#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 135 */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
/* Slot 138 is reserved */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
/* Slot 139 is reserved */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
/* Slot 140 is reserved */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
/* Slot 141 is reserved */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
/* Slot 142 is reserved */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */
/* Slot 143 is reserved */
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
/* Slot 147 is reserved */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
/* Slot 148 is reserved */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xUnregisterIMInstantiateCallback) /* 150 */
#define XSetLocaleModifiers \
	(tkIntXlibStubsPtr->xSetLocaleModifiers) /* 151 */
/* Slot 149 is reserved */
/* Slot 150 is reserved */
/* Slot 151 is reserved */
#define XOpenIM \
	(tkIntXlibStubsPtr->xOpenIM) /* 152 */
/* Slot 152 is reserved */
#define XGetIMValues \
	(tkIntXlibStubsPtr->xGetIMValues) /* 153 */
/* Slot 153 is reserved */
#define XSetIMValues \
	(tkIntXlibStubsPtr->xSetIMValues) /* 154 */
/* Slot 154 is reserved */
#define XCreateFontSet \
	(tkIntXlibStubsPtr->xCreateFontSet) /* 155 */
/* Slot 155 is reserved */
#define XFreeStringList \
	(tkIntXlibStubsPtr->xFreeStringList) /* 156 */
/* Slot 156 is reserved */
#define XkbKeycodeToKeysym \
	(tkIntXlibStubsPtr->xkbKeycodeToKeysym) /* 157 */
#define XkbOpenDisplay \
	(tkIntXlibStubsPtr->xkbOpenDisplay) /* 158 */
/* Slot 157 is reserved */
#define TkUnusedStubEntry \
	(tkIntXlibStubsPtr->tkUnusedStubEntry) /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#ifdef MAC_OSX_TK /* AQUA */
#define XSetDashes \
	(tkIntXlibStubsPtr->xSetDashes) /* 0 */
#define XGetModifierMapping \
	(tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */
#define XCreateImage \
	(tkIntXlibStubsPtr->xCreateImage) /* 2 */
#define XGetImage \
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
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







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+














-
-
+









-
-
+
-
-
+








-
-
+
-
-
+
-
-
+



-
-
+


-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+






-
-
+
-
-
+
-
-
-
-
-
-
+
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+


-
-
-
+
+
+





-
-
-
-



+
+

	(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 */
/* 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 */
#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 */
/* Slot 100 is reserved */
#define XGetWindowAttributes \
	(tkIntXlibStubsPtr->xGetWindowAttributes) /* 101 */
/* Slot 101 is reserved */
#define XGetWMColormapWindows \
	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 102 */
/* Slot 102 is reserved */
#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 103 */
/* Slot 103 is reserved */
#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 104 */
/* Slot 104 is reserved */
#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 105 */
/* Slot 105 is reserved */
#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 */
/* Slot 113 is reserved */
#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 */
/* Slot 121 is reserved */
#define XCreateWindow \
	(tkIntXlibStubsPtr->xCreateWindow) /* 122 */
/* 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 */
#define XLowerWindow \
	(tkIntXlibStubsPtr->xLowerWindow) /* 129 */
#define XFillArcs \
	(tkIntXlibStubsPtr->xFillArcs) /* 130 */
/* Slot 130 is reserved */
#define XDrawArcs \
	(tkIntXlibStubsPtr->xDrawArcs) /* 131 */
/* Slot 131 is reserved */
#define XDrawRectangles \
	(tkIntXlibStubsPtr->xDrawRectangles) /* 132 */
/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
/* Slot 136 is reserved */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
/* Slot 138 is reserved */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
/* Slot 139 is reserved */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
/* Slot 140 is reserved */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
/* Slot 141 is reserved */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
/* Slot 142 is reserved */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */
/* Slot 143 is reserved */
#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 144 */
#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 145 */
#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 146 */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
/* Slot 147 is reserved */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
/* Slot 148 is reserved */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xUnregisterIMInstantiateCallback) /* 150 */
#define XSetLocaleModifiers \
	(tkIntXlibStubsPtr->xSetLocaleModifiers) /* 151 */
/* Slot 149 is reserved */
/* Slot 150 is reserved */
/* Slot 151 is reserved */
#define XOpenIM \
	(tkIntXlibStubsPtr->xOpenIM) /* 152 */
/* Slot 152 is reserved */
#define XGetIMValues \
	(tkIntXlibStubsPtr->xGetIMValues) /* 153 */
/* Slot 153 is reserved */
#define XSetIMValues \
	(tkIntXlibStubsPtr->xSetIMValues) /* 154 */
/* Slot 154 is reserved */
#define XCreateFontSet \
	(tkIntXlibStubsPtr->xCreateFontSet) /* 155 */
/* Slot 155 is reserved */
#define XFreeStringList \
	(tkIntXlibStubsPtr->xFreeStringList) /* 156 */
/* Slot 156 is reserved */
#define XkbKeycodeToKeysym \
	(tkIntXlibStubsPtr->xkbKeycodeToKeysym) /* 157 */
#define XkbOpenDisplay \
	(tkIntXlibStubsPtr->xkbOpenDisplay) /* 158 */
#endif /* MACOSX */
#define TkUnusedStubEntry \
	(tkIntXlibStubsPtr->tkUnusedStubEntry) /* 158 */
#endif /* AQUA */

#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

#undef TkUnusedStubEntry

#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
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"

#ifdef _WIN32
#include "tkWinInt.h"
#include "tkInt.h"
#endif

typedef struct {
    Tk_OptionTable listboxOptionTable;
				/* Table defining configuration options
				 * available for the listbox. */
    Tk_OptionTable itemAttrOptionTable;
				/* Table defining configuration options
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245

246
247
248

249
250

251
252

253
254
255

256
257
258
259


260
261
262


263
264

265
266

267
268

269
270

271
272
273


274
275

276
277
278
279


280
281

282
283

284
285

286
287
288
289


290
291

292
293
294

295
296
297

298
299
300


301
302

303
304
305

306
307

308
309
310

311
312
313

314
315

316
317
318
319
320
321
322
323
324
325
326



327
328
329

330
331
332
333
334
335
336
337







338
339
340
341



342
343

344
345
346
347
348
349
350
212
213
214
215
216
217
218




219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236

237
238
239

240
241

242
243

244
245
246

247
248
249


250
251
252


253
254
255

256
257

258
259

260
261

262
263


264
265
266

267
268
269


270
271
272

273
274

275
276

277
278
279


280
281
282

283
284
285

286
287
288

289
290


291
292
293

294
295
296

297
298

299
300
301

302
303
304

305
306

307
308
309
310
311
312
313
314
315



316
317
318

319

320
321







322
323
324
325
326
327
328




329
330
331


332
333
334
335
336
337
338
339







-
-
-
-















-
+


-
+


-
+

-
+

-
+


-
+


-
-
+
+

-
-
+
+

-
+

-
+

-
+

-
+

-
-
+
+

-
+


-
-
+
+

-
+

-
+

-
+


-
-
+
+

-
+


-
+


-
+

-
-
+
+

-
+


-
+

-
+


-
+


-
+

-
+








-
-
-
+
+
+
-

-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
+







 * below.
 */

enum state {
    STATE_DISABLED, STATE_NORMAL
};

static const char *const stateStrings[] = {
    "disabled", "normal", NULL
};

enum activeStyle {
    ACTIVE_STYLE_DOTBOX, ACTIVE_STYLE_NONE, ACTIVE_STYLE_UNDERLINE
};

static const char *const activeStyleStrings[] = {
    "dotbox", "none", "underline", NULL
};

/*
 * 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),
	DEF_LISTBOX_ACTIVE_STYLE, -1, Tk_Offset(Listbox, activeStyle),
	0, activeStyleStrings, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_LISTBOX_BG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, normalBorder),
	 DEF_LISTBOX_BG_COLOR, -1, Tk_Offset(Listbox, normalBorder),
	 0, DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	 NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	 NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_LISTBOX_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, borderWidth),
	 DEF_LISTBOX_BORDER_WIDTH, -1, Tk_Offset(Listbox, borderWidth),
	 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_LISTBOX_CURSOR, TCL_INDEX_NONE, offsetof(Listbox, 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, TCL_INDEX_NONE,
	 offsetof(Listbox, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
	 "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, TCL_INDEX_NONE,
	 offsetof(Listbox, exportSelection), 0, 0, 0},
	 "ExportSelection", DEF_LISTBOX_EXPORT_SELECTION, -1,
	 Tk_Offset(Listbox, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	 NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	 DEF_LISTBOX_FONT, TCL_INDEX_NONE, offsetof(Listbox, tkfont), 0, 0, 0},
	 DEF_LISTBOX_FONT, -1, Tk_Offset(Listbox, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	 DEF_LISTBOX_FG, TCL_INDEX_NONE, offsetof(Listbox, fgColorPtr), 0, 0, 0},
	 DEF_LISTBOX_FG, -1, Tk_Offset(Listbox, fgColorPtr), 0, 0, 0},
    {TK_OPTION_INT, "-height", "height", "Height",
	 DEF_LISTBOX_HEIGHT, TCL_INDEX_NONE, offsetof(Listbox, height), 0, 0, 0},
	 DEF_LISTBOX_HEIGHT, -1, Tk_Offset(Listbox, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_LISTBOX_HIGHLIGHT_BG, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightBgColorPtr), 0, 0, 0},
	 "HighlightBackground", DEF_LISTBOX_HIGHLIGHT_BG, -1,
	 Tk_Offset(Listbox, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_LISTBOX_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Listbox, highlightColorPtr),
	 DEF_LISTBOX_HIGHLIGHT, -1, Tk_Offset(Listbox, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightWidth), 0, 0, 0},
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, -1,
	 Tk_Offset(Listbox, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_LISTBOX_JUSTIFY, TCL_INDEX_NONE, offsetof(Listbox, justify), 0, 0, 0},
	DEF_LISTBOX_JUSTIFY, -1, Tk_Offset(Listbox, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_LISTBOX_RELIEF, TCL_INDEX_NONE, offsetof(Listbox, relief), 0, 0, 0},
	 DEF_LISTBOX_RELIEF, -1, Tk_Offset(Listbox, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	 DEF_LISTBOX_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selBorder),
	 DEF_LISTBOX_SELECT_COLOR, -1, Tk_Offset(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},
	 "BorderWidth", DEF_LISTBOX_SELECT_BD, -1,
	 Tk_Offset(Listbox, selBorderWidth), 0, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	 DEF_LISTBOX_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selFgColorPtr),
	 DEF_LISTBOX_SELECT_FG_COLOR, -1, Tk_Offset(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),
	 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, TCL_INDEX_NONE, offsetof(Listbox, setGrid), 0, 0, 0},
	 DEF_LISTBOX_SET_GRID, -1, Tk_Offset(Listbox, setGrid), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_LISTBOX_STATE, TCL_INDEX_NONE, offsetof(Listbox, state),
	0, stateStrings, 0},
	DEF_LISTBOX_STATE, -1, Tk_Offset(Listbox, state),
	0, &tkStateStrings[1], 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	 DEF_LISTBOX_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Listbox, 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, TCL_INDEX_NONE, offsetof(Listbox, width), 0, 0, 0},
	 DEF_LISTBOX_WIDTH, -1, Tk_Offset(Listbox, width), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, xScrollCmd),
	 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, TCL_INDEX_NONE, offsetof(Listbox, yScrollCmd),
	 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, TCL_INDEX_NONE, offsetof(Listbox, listVarName),
	 DEF_LISTBOX_LIST_VARIABLE, -1, Tk_Offset(Listbox, listVarName),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * The itemAttrOptionSpecs table defines the valid configuration options for
 * listbox items.
 */

static const Tk_OptionSpec itemAttrOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, border),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
    {TK_OPTION_BORDER, "-background", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, border),
     TK_OPTION_NULL_OK, NULL, 0},
     DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
     NULL, 0, -1, 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,
     NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, fgColor),
     TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BORDER, "-selectbackground", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, selBorder),
     TK_OPTION_NULL_OK, NULL, 0},
     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,
    {TK_OPTION_COLOR, "-selectforeground", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, selFgColor),
     TK_OPTION_NULL_OK, NULL, 0},
     DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, NULL, 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.
 */
373
374
375
376
377
378
379
380

381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413


414
415
416
417
418
419
420
362
363
364
365
366
367
368

369
370
371

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400


401
402
403
404
405
406
407
408
409







-
+


-
+















-
+












-
-
+
+







    "mark", "dragto", NULL
};
enum scancommand {
    SCAN_MARK, SCAN_DRAGTO
};

static const char *const indexNames[] = {
    "active", "anchor", NULL
    "active", "anchor", "end", NULL
};
enum indices {
    INDEX_ACTIVE, INDEX_ANCHOR
    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(void *memPtr);
static Tcl_FreeProc	DestroyListbox;
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 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);
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
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







-
+







-












-
+







-
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ListboxObjCmd(
    ClientData dummy,	/* NULL. */
    ClientData clientData,	/* 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);
    optionTables = 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));
	optionTables = ckalloc(sizeof(ListboxOptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
	 */

	Tcl_SetAssocData(interp, "ListboxOptionTables",
		DestroyListboxOptionTables, optionTables);
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
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







-
+










-
+

-
+








    /*
     * 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));
    listPtr			 = 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));
    listPtr->selection		 = ckalloc(sizeof(Tcl_HashTable));
    Tcl_InitHashTable(listPtr->selection, TCL_ONE_WORD_KEYS);
    listPtr->itemAttrTable	 = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
    listPtr->itemAttrTable	 = 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;
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
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







-
+










-
+







    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,
    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_SetObjResult(interp, Tk_NewWindowObj(listPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(listPtr->tkwin));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxWidgetObjCmd --
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
592
593
594
595
596
597
598

599
600
601
602
603
604
605
606







-
+







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;
    Listbox *listPtr = clientData;
    int cmdIndex, index;
    int result = TCL_OK;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
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
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







-
+











-
+







    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
	}

	objPtr = Tk_GetOptionValue(interp, listPtr,
	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:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, listPtr,
	    objPtr = Tk_GetOptionInfo(interp, (char *) listPtr,
		    listPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727







-
+







	 * 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_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(i));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;
    }

838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
826
827
828
829
830
831
832

833
834
835
836
837
838
839
840







-
+







	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
	if (result != TCL_OK) {
	    break;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	result = TCL_OK;
	break;

    case COMMAND_INSERT:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?element ...?");
	    result = TCL_ERROR;
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
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







-
+




















-
+







    }

    case COMMAND_ITEMCONFIGURE: {
	ItemAttr *attrPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index ?-option value ...?");
		    "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_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,
	    objPtr = Tk_GetOptionInfo(interp, (char *) attrPtr,
		    listPtr->itemAttrOptionTable,
		    (objc == 4) ? objv[3] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);
953
954
955
956
957
958
959
960

961
962
963
964
965
966
967
941
942
943
944
945
946
947

948
949
950
951
952
953
954
955







-
+







	}

	result = Tcl_GetIntFromObj(interp, objv[2], &y);
	if (result != TCL_OK) {
	    break;
	}
	index = NearestListboxElement(listPtr, y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	result = TCL_OK;
	break;
    }

    case COMMAND_SCAN: {
	int x, y, scanCmdIndex;

1041
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
1029
1030
1031
1032
1033
1034
1035

1036
1037
1038
1039
1040
1041
1042
1043







-
+







	break;
    case COMMAND_SIZE:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    result = TCL_ERROR;
	    break;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(listPtr->nElements));
	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);
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
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







-
+
-











-
+














-
-
-
-
+
+
+
+







    /*
     * 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;
	int pixelWidth, stringLen, 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);
	stringRep = Tcl_GetStringFromObj(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);
	results[0] = Tcl_NewIntObj(x);
	results[1] = Tcl_NewIntObj(y);
	results[2] = Tcl_NewIntObj(pixelWidth);
	results[3] = Tcl_NewIntObj(fm.linespace);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
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 (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;
	case TK_SCROLL_UNITS:
	    offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    break;
	default:
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, offset);
    }
    return TCL_OK;
}

/*
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369







-







	    } else {
		index = listPtr->topIndex + count;
	    }
	    break;
	case TK_SCROLL_UNITS:
	    index = listPtr->topIndex + count;
	    break;
	case TK_SCROLL_ERROR:
	default:
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    }
    return TCL_OK;
}
1408
1409
1410
1411
1412
1413
1414
1415

1416
1417
1418
1419
1420

1421
1422
1423
1424

1425
1426
1427
1428
1429
1430
1431
1394
1395
1396
1397
1398
1399
1400

1401
1402
1403
1404
1405

1406
1407
1408
1409

1410
1411
1412
1413
1414
1415
1416
1417







-
+




-
+



-
+







{
    int isNew;
    Tcl_HashEntry *entry;
    ItemAttr *attrs;

    entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, KEY(index), &isNew);
    if (isNew) {
	attrs = (ItemAttr *)ckalloc(sizeof(ItemAttr));
	attrs = ckalloc(sizeof(ItemAttr));
	attrs->border = NULL;
	attrs->selBorder = NULL;
	attrs->fgColor = NULL;
	attrs->selFgColor = NULL;
	Tk_InitOptions(interp, attrs, listPtr->itemAttrOptionTable,
	Tk_InitOptions(interp, (char *)attrs, listPtr->itemAttrOptionTable,
		listPtr->tkwin);
	Tcl_SetHashValue(entry, attrs);
    } else {
	attrs = (ItemAttr *)Tcl_GetHashValue(entry);
	attrs = Tcl_GetHashValue(entry);
    }
    return attrs;
}

/*
 *----------------------------------------------------------------------
 *
1442
1443
1444
1445
1446
1447
1448
1449

1450
1451
1452
1453
1454
1455
1456
1428
1429
1430
1431
1432
1433
1434

1435
1436
1437
1438
1439
1440
1441
1442







-
+







 *	Everything associated with the listbox is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListbox(
    void *memPtr)		/* Info about listbox widget. */
    char *memPtr)		/* Info about listbox widget. */
{
    Listbox *listPtr = (Listbox *)memPtr;
    Tcl_HashEntry *entry;
    Tcl_HashSearch search;

    /*
     * If we have an internal list object, free it.
1524
1525
1526
1527
1528
1529
1530
1531

1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1510
1511
1512
1513
1514
1515
1516

1517
1518


1519
1520
1521
1522
1523
1524
1525







-
+

-
-







 *
 *----------------------------------------------------------------------
 */

static void
DestroyListboxOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *dummy)		/* Pointer to the calling interp */
    Tcl_Interp *interp)		/* Pointer to the calling interp */
{
    (void)dummy;

    ckfree(clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *
1578
1579
1580
1581
1582
1583
1584
1585

1586
1587
1588
1589
1590
1591
1592
1562
1563
1564
1565
1566
1567
1568

1569
1570
1571
1572
1573
1574
1575
1576







-
+








    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, listPtr,
	    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.
1724
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738
1708
1709
1710
1711
1712
1713
1714

1715
1716
1717
1718
1719
1720
1721
1722







-
+







    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,
    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
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1764







-
+







static void
ListboxWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    Listbox *listPtr = (Listbox *)instanceData;
    Listbox *listPtr = 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
1821
1822
1823
1824
1825
1826
1827

1828
1829
1830
1831

1832

1833
1834
1835
1836
1837
1838
1839







-
+

+

-
+
-







 *--------------------------------------------------------------
 */

static void
DisplayListbox(
    ClientData clientData)	/* Information about window. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Listbox *listPtr = clientData;
    Tk_Window tkwin = listPtr->tkwin;
    Display *disp = listPtr->display;
    GC gc;
    int i, limit, x, y, prevSelected, freeGC;
    int i, limit, x, y, prevSelected, freeGC, stringLen;
    TkSizeT stringLen;
    Tk_FontMetrics fm;
    Tcl_Obj *curElement;
    Tcl_HashEntry *entry;
    const char *stringRep;
    ItemAttr *attrs;
    Tk_3DBorder selectedBg;
    XGCValues gcValues;
1894
1895
1896
1897
1898
1899
1900
1901

1902
1903
1904
1905
1906
1907
1908
1878
1879
1880
1881
1882
1883
1884

1885
1886
1887
1888
1889
1890
1891
1892







-
+







     * Redrawing is done in a temporary pixmap that is allocated here and
     * freed at the end of the procedure. All drawing is done to the pixmap,
     * and the pixmap is copied to the screen at the end of the procedure.
     * This provides the smoothest possible visual effects (no flashing on the
     * screen).
     */

    pixmap = Tk_GetPixmap(listPtr->display, Tk_WindowId(tkwin),
    pixmap = Tk_GetPixmap(disp, Tk_WindowId(tkwin),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
    pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */
    Tk_Fill3DRectangle(tkwin, pixmap, listPtr->normalBorder, 0, 0,
	    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

1924
1925
1926
1927
1928
1929
1930
1931

1932
1933
1934
1935
1936
1937
1938
1908
1909
1910
1911
1912
1913
1914

1915
1916
1917
1918
1919
1920
1921
1922







-
+







    }
    prevSelected = 0;

    for (i = listPtr->topIndex; i <= limit; i++) {
	int width = Tk_Width(tkwin);	/* zeroth approx to silence warning */

	x = listPtr->inset;
	y = ((i - listPtr->topIndex) * listPtr->lineHeight) + listPtr->inset;
	y = (i - listPtr->topIndex) * listPtr->lineHeight + listPtr->inset;
	gc = listPtr->textGC;
	freeGC = 0;

	/*
	 * Lookup this item in the item attributes table, to see if it has
	 * special foreground/background colors.
	 */
1957
1958
1959
1960
1961
1962
1963
1964

1965
1966
1967
1968
1969
1970
1971
1941
1942
1943
1944
1945
1946
1947

1948
1949
1950
1951
1952
1953
1954
1955







-
+








		/*
		 * If there is attribute information for this item, adjust the
		 * drawing accordingly.
		 */

		if (entry != NULL) {
		    attrs = (ItemAttr *)Tcl_GetHashValue(entry);
		    attrs = Tcl_GetHashValue(entry);

		    /*
		     * Default GC has the values from the widget at large.
		     */

		    if (listPtr->selFgColorPtr) {
			gcValues.foreground = listPtr->selFgColorPtr->pixel;
2038
2039
2040
2041
2042
2043
2044
2045

2046
2047
2048
2049
2050
2051
2052
2022
2023
2024
2025
2026
2027
2028

2029
2030
2031
2032
2033
2034
2035
2036







-
+







	    } 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);
		    attrs = Tcl_GetHashValue(entry);
		    gcValues.foreground = listPtr->fgColorPtr->pixel;
		    gcValues.font = Tk_FontId(listPtr->tkfont);
		    gcValues.graphics_exposures = False;
		    mask = GCForeground | GCFont | GCGraphicsExposures;

		    /*
		     * If the item has its own background color, draw it now.
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
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







-
+















-
+












-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
+

-
+

-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
-

-
-
-
-






-
+

-




-
+







	}

	/*
	 * Draw the actual text of this item.
	 */

        Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
        stringRep = TkGetStringFromObj(curElement, &stringLen);
        stringRep = Tcl_GetStringFromObj(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,
        Tk_DrawChars(disp, 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);
		Tk_UnderlineChars(disp, 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)
		y = (i - listPtr->topIndex) * listPtr->lineHeight
			+ listPtr->inset;
		width = Tk_Width(tkwin) - 2*listPtr->inset - 1;
		width = Tk_Width(tkwin) - 2*listPtr->inset;

		gcValues.line_style = LineOnOffDash;
		gcValues.line_width = listPtr->selBorderWidth;
		if (gcValues.line_width <= 0) {
		    gcValues.line_width  = 1;
		}
		gcValues.dash_offset = 0;
		gcValues.dashes = 1;

		TkDrawDottedRect(disp, pixmap, gc, x, y,
		/*
		 * You would think the XSetDashes was necessary, but it
		 * appears that the default dotting for just saying we want
		 * dashes appears to work correctly.
		 static char dashList[] = { 1 };
		 static int dashLen = sizeof(dashList);
		 XSetDashes(listPtr->display, gc, 0, dashList, dashLen);
			width, listPtr->lineHeight);
		 */

		mask = GCLineWidth | GCLineStyle | GCDashList | GCDashOffset;
		XChangeGC(listPtr->display, gc, mask, &gcValues);
		XDrawRectangle(listPtr->display, pixmap, gc, x, y,
			(unsigned) width, (unsigned) listPtr->lineHeight - 1);
		if (!freeGC) {
		    /*
		     * Don't bother changing if it is about to be freed.
		     */

		    gcValues.line_style = LineSolid;
		    XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues);
		    XChangeGC(disp, gc, GCLineStyle, &gcValues);
		}
#endif /* _WIN32 */
	    }
	}

	if (freeGC) {
	    Tk_FreeGC(listPtr->display, gc);
	    Tk_FreeGC(disp, gc);
	}
    }

    /*
     * Redraw the border for the listbox to make sure that it's on top of any
     * of the text of the listbox entries.
     */
2196
2197
2198
2199
2200
2201
2202
2203
2204


2205
2206

2207
2208
2209
2210
2211
2212
2213
2143
2144
2145
2146
2147
2148
2149


2150
2151


2152
2153
2154
2155
2156
2157
2158
2159







-
-
+
+
-
-
+







		    listPtr->highlightWidth, pixmap);
	} else {
	    TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
		    listPtr->highlightWidth, pixmap);
	}
    }
#ifndef TK_NO_DOUBLE_BUFFERING
    XCopyArea(listPtr->display, pixmap, Tk_WindowId(tkwin),
	    listPtr->textGC, 0, 0, (unsigned) Tk_Width(tkwin),
    XCopyArea(disp, pixmap, Tk_WindowId(tkwin), listPtr->textGC, 0, 0,
	    (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0);
	    (unsigned) Tk_Height(tkwin), 0, 0);
    Tk_FreePixmap(listPtr->display, pixmap);
    Tk_FreePixmap(disp, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxComputeGeometry --
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
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







-
+
-




















-
+







				 * 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;
    int width, height, pixelWidth, pixelHeight, textLength, 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);
	    text = Tcl_GetStringFromObj(element, &textLength);
	    Tk_GetFontMetrics(listPtr->tkfont, &fm);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
	    if (pixelWidth > listPtr->maxWidth) {
		listPtr->maxWidth = pixelWidth;
	    }
	}
    }
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
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







-
+
-










-
+







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;
    int i, oldMaxWidth, pixelWidth, result, length;
    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);
	stringRep = Tcl_GetStringFromObj(objv[i], &length);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	if (pixelWidth > listPtr->maxWidth) {
	    listPtr->maxWidth = pixelWidth;
	}
    }

    /*
2440
2441
2442
2443
2444
2445
2446
2447

2448
2449
2450
2451
2452
2453
2454
2455
2384
2385
2386
2387
2388
2389
2390

2391

2392
2393
2394
2395
2396
2397
2398







-
+
-








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;
    int count, i, widthChanged, length, 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.
2496
2497
2498
2499
2500
2501
2502
2503

2504
2505
2506
2507
2508
2509
2510
2439
2440
2441
2442
2443
2444
2445

2446
2447
2448
2449
2450
2451
2452
2453







-
+







	 * 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);
	    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
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







-
+
















-
+







 */

static void
ListboxEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Listbox *listPtr = 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);
	    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
2632
2633
2634
2635
2636
2637
2638

2639
2640
2641
2642
2643
2644
2645
2646







-
+







 *----------------------------------------------------------------------
 */

static void
ListboxCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Listbox *listPtr = 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
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







-
+





-


-
-
-
-
-
-
-
-
-














+
+
+
+
+
+
+
+








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
    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;
    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;
	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
2792
2793
2794
2795
2796
2797
2798








2799
2800
2801
2802
2803
2804
2805
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754







+
+
+
+
+
+
+
+







	y = strtol(start, &end, 0);
	if ((start == end) || (*end != '\0')) {
	    goto badIndex;
	}
	*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.
     */

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
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
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







-
+


-
+


-
+



-
+

-
+
-







 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
ListboxFetchSelection(
    ClientData clientData,	/* Information about listbox widget. */
    TkSizeT offset,			/* Offset within selection of first byte to be
    int 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,
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Listbox *listPtr = clientData;
    Tcl_DString selection;
    int count, needNewline, i;
    int length, count, needNewline, stringLen, i;
    TkSizeT length, stringLen;
    Tcl_Obj *curElement;
    const char *stringRep;
    Tcl_HashEntry *entry;

    if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) {
	return -1;
    }
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
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







-
+














-
+
+


-
-
-
+
+

-
+







	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);
	    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.
     */

    if (length <= offset) {
    count = length - offset;
    if (count <= 0) {
	count = 0;
    } else {
	count = length - offset;
	if (count > (int)maxBytes) {
	    count = (int)maxBytes;
	if (count > maxBytes) {
	    count = maxBytes;
	}
	memcpy(buffer, Tcl_DStringValue(&selection) + offset, count);
	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
3143
3144
3145
3146
3147
3148
3149

3150
3151
3152
3153
3154
3155
3156
3157







-
+







 *----------------------------------------------------------------------
 */

static void
ListboxLostSelection(
    ClientData clientData)	/* Information about listbox widget. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Listbox *listPtr = clientData;

    if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp))
	    && (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
3173
3174
3175
3176
3177
3178
3179

3180
3181
3182
3183
3184
3185
3186
3187







-
+







 *----------------------------------------------------------------------
 */

static void
GenerateListboxSelectEvent(
    Listbox *listPtr)		/* Information about widget. */
{
    Tk_SendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);
    TkSendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyRedrawRange --
 *
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265

3266
3267
3268
3269
3270
3271
3272
3202
3203
3204
3205
3206
3207
3208



3209

3210
3211
3212
3213
3214
3215
3216
3217







-
-
-

-
+







    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,
     * We don't have to 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;
3437
3438
3439
3440
3441
3442
3443
3444

3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3382
3383
3384
3385
3386
3387
3388

3389
3390
3391
3392


3393
3394
3395
3396
3397
3398
3399







-
+



-
-







ListboxListVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    Listbox *listPtr = (Listbox *)clientData;
    Listbox *listPtr = 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) {

Changes to generic/tkMacWinMenu.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkMacWinMenu.c --
 *
 *	This module implements the common elements of the Mac and Windows
 *	specific features of menus. This file is not used for UNIX.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenu.h"
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+







 */

static int
PreprocessMenu(
    TkMenu *menuPtr)
{
    int index, result, finished;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    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.
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76







-
+







     * 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++) {
	for (index = 0; index < 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;
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139







-
+







 *----------------------------------------------------------------------
 */

int
TkPreprocessMenu(
    TkMenu *menuPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->postCommandGeneration++;
    menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration;
    return PreprocessMenu(menuPtr);
}

Changes to generic/tkMain.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
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
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"

#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD)
extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
MODULE_SCOPE void TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
#endif

/*
 * The default prompt used when the user has not overridden it.
 */

static const char DEFAULT_PRIMARY_PROMPT[] = "% ";
static const char ENCODING_ERROR[] = "\n\t(encoding error in stderr)";

/*
 * 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
 * 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.
 * 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 {
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;
#ifdef __cplusplus
63
64
65
66
67
68
69

70
71

72
73

74
75

76
77

78
79
80
81
82
83
84

85
86
87
88
89
90
91
65
66
67
68
69
70
71
72
73

74
75
76
77
78

79
80

81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







+

-
+


+

-
+

-
+






-
+








static inline Tcl_Obj *
NewNativeObj(
    TCHAR *string)
{
    Tcl_Obj *obj;
    Tcl_DString ds;
    const char *str;

#ifdef UNICODE
#if defined(_WIN32) && defined(UNICODE)
    Tcl_DStringInit(&ds);
    Tcl_WCharToUtfDString(string, wcslen(string), &ds);
    str = Tcl_DStringValue(&ds);
#else
    Tcl_ExternalToUtfDString(NULL, (char *) string, -1, &ds);
    str = Tcl_ExternalToUtfDString(NULL, (char *)string, strlen(string), &ds);
#endif
    obj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    obj = Tcl_NewStringObj(str, 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
 * include tclInt.h or tclPort.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
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171

172
173
174
175
176





177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

200
201

202
203
204

205
206
207


208
209
210
211
212
213
214
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209


210

211

212
213


214
215
216
217
218
219
220
221
222







-
+



















-
+




















-
+









+





+
+
+
+
+





-
+
















-
+
-
-
+
-

-
+

-
-
+
+







	     || (GetFileType(handle) == FILE_TYPE_UNKNOWN)
	     || (GetFileType(handle) == FILE_TYPE_CHAR);
}
#else
extern int		isatty(int fd);
#endif

typedef struct InteractiveState {
typedef struct {
    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);
static void		StdinProc(void *clientData, int mask);

/*
 *----------------------------------------------------------------------
 *
 * Tk_MainEx --
 *
 *	Main program for Wish and most other Tk-based applications.
 *
 * Results:
 *	None. This function never returns (it exits the process when it's
 *	done).
 *
 * Side effects:
 *	This function initializes the Tk world and then starts interpreting
 *	commands; almost anything could happen, depending on the script being
 *	interpreted.
 *
 *----------------------------------------------------------------------
 */

void
TCL_NORETURN1 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)
{
    int i=0;			/* argv[i] index */
    Tcl_Obj *path, *argvPtr, *appName;
    const char *encodingName;
    int code, nullStdin = 0;
    Tcl_Channel chan;
    InteractiveState is;

    if (0 < argc) {
	--argc;			/* "consume" argv[0] */
	++i;
    }

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
    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)) {
	    TkCygwinMainEx(argc, argv, appInitProc, interp);
		/* Should never reach here. */
		return;
	    /* Only returns when Tk_MainEx() was not found */
	    }
	} else {
	    int i;
	    int j;

	    for (i = 1; i < argc; ++i) {
		if (!_tcscmp(argv[i], TEXT("-display"))) {
	    for (j = 1; j < argc; ++j) {
		if (!strcmp(argv[j], "-display")) {
		    goto loadCygwinTk;
		}
	    }
	}
    }
#endif

246
247
248
249
250
251
252

253
254


255
256
257
258
259
260


261
262
263
264


265
266

267
268
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287

288
289
290
291
292
293
294
254
255
256
257
258
259
260
261


262
263
264
265
266
267


268
269
270
271


272
273
274

275
276
277

278
279
280
281
282
283
284
285
286
287
288


289

290
291
292
293

294
295
296
297
298
299
300
301







+
-
-
+
+




-
-
+
+


-
-
+
+

-
+


-
+










-
-

-
+



-
+







	 *  -encoding ENCODING FILENAME
	 * or like
	 *  FILENAME
	 * or like
	 *  -file FILENAME		(ancient history support only)
	 */

	/* mind argc is being adjusted as we proceed */
	if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
		&& (TEXT('-') != argv[3][0])) {
	if ((argc >= 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
		&& ('-' != 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])) {
	    i += 3;
	} else if ((argc >= 1) && ('-' != argv[1][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[1]), NULL);
	    argc--;
	    argv++;
	} else if ((argc > 2) && (length = _tcslen(argv[1]))
	    i++;
	} else if ((argc >= 2) && (length = _tcslen(argv[1]))
		&& (length > 1) && (0 == _tcsncmp(TEXT("-file"), argv[1], length))
		&& (TEXT('-') != argv[2][0])) {
		&& ('-' != argv[2][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[2]), NULL);
	    argc -= 2;
	    argv += 2;
	    i += 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);
    Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewIntObj(argc), TCL_GLOBAL_ONLY);

    argvPtr = Tcl_NewListObj(0, NULL);
    while (argc--) {
	Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++));
	Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(argv[i++]));
    }
    Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);

    /*
     * Set the "tcl_interactive" variable.
     */

303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324







-
+







    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);
	    Tcl_NewBooleanObj(!path && (is.tty || nullStdin)), TCL_GLOBAL_ONLY);

    /*
     * Invoke application-specific initialization.
     */

    if (appInitProc(interp) != TCL_OK) {
	TkpDisplayWarning(Tcl_GetString(Tcl_GetObjResult(interp)),
398
399
400
401
402
403
404
405
406


407
408
409
410

411
412
413

414
415

416
417

418






419
420
421
422

423
424
425
426
427
428
429
405
406
407
408
409
410
411


412
413
414
415
416

417
418
419
420
421
422

423
424

425
426
427
428
429
430
431
432
433


434
435
436
437
438
439
440
441
442







-
-
+
+



-
+



+

-
+

-
+

+
+
+
+
+
+

-
-

+







 *	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))
    void *clientData,	/* The state of interactive cmd line */
    int mask)			/* Not used. */
{
    char *cmd;
    int code;
    TkSizeT count;
    int length;
    InteractiveState *isPtr = (InteractiveState *)clientData;
    Tcl_Channel chan = isPtr->input;
    Tcl_Interp *interp = isPtr->interp;
    (void)mask;

    count = Tcl_Gets(chan, &isPtr->line);
    length = Tcl_Gets(chan, &isPtr->line);

    if ((count == TCL_IO_FAILURE) && !isPtr->gotPartial) {
    if ((length < 0) && !isPtr->gotPartial) {
	if (isPtr->tty) {
	    /*
	     * Would be better to find a way to exit the mainLoop? Or perhaps
	     * evaluate [exit]? Leaving as is for now due to compatibility
	     * concerns.
	     */

	    Tcl_Exit(0);
	} else {
	    Tcl_DeleteChannelHandler(chan, StdinProc, isPtr);
	}
	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)) {
437
438
439
440
441
442
443
444
445
446
447



448
449
450
451
452
453
454
455
456
457






















458
459
460
461
462
463
464
450
451
452
453
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







-
-
-
-
+
+
+


-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







     * 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);
    isPtr->input = chan = Tcl_GetStdChannel(TCL_STDIN);
    if (chan != NULL) {
	Tcl_CreateChannelHandler(chan, 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 (code != TCL_OK) {
	chan = Tcl_GetStdChannel(TCL_STDERR);

	if (chan != NULL) {
	    if (Tcl_WriteObj(chan, Tcl_GetObjResult(interp)) < 0) {
		Tcl_WriteChars(chan, ENCODING_ERROR, -1);
	    }
	    Tcl_WriteChars(chan, "\n", 1);
	}
    } else if (isPtr->tty) {
	Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
	chan = Tcl_GetStdChannel(TCL_STDOUT);

	Tcl_IncrRefCount(resultPtr);
	(void)Tcl_GetStringFromObj(resultPtr, &length);
	if ((length > 0) && (chan != NULL)) {
	    if (Tcl_WriteObj(chan, resultPtr) < 0) {
		Tcl_WriteChars(chan, "\n\t(encoding error in stdout)", -1);
	    }
	    Tcl_WriteChars(chan, "\n", 1);
	}
	Tcl_DecrRefCount(resultPtr);
    }

    /*
     * If a tty stdin is still around, output a prompt.
     */

  prompt:
506
507
508
509
510
511
512
513
514
515
516
517
518






519
520
521
522
523
524
525
532
533
534
535
536
537
538






539
540
541
542
543
544
545
546
547
548
549
550
551







-
-
-
-
-
-
+
+
+
+
+
+







	    }
	}
    } 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);
		}
	    chan = Tcl_GetStdChannel(TCL_STDERR);
	    if (chan != NULL) {
	    if (Tcl_WriteObj(chan, Tcl_GetObjResult(interp)) < 0) {
		Tcl_WriteChars(chan, ENCODING_ERROR, -1);
	    }
		Tcl_WriteChars(chan, "\n", 1);
	    }
	    goto defaultPrompt;
	}
    }

    chan = Tcl_GetStdChannel(TCL_STDOUT);
    if (chan != NULL) {
Changes to generic/tkMenu.c.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125

126
127
128

129
130
131

132
133
134

135
136
137

138
139
140

141
142
143


144
145
146

147
148
149

150
151
152

153
154
155

156
157
158

159
160
161
162


163
164

165
166
167
168
169
170
171

172
173
174
175
176
177
178

179
180
181

182
183
184

185
186
187

188
189
190

191
192
193

194
195

196
197
198
199
200
201

202
203
204

205
206
207

208
209
210

211
212
213

214
215

216
217
218
219
220
221

222
223

224
225
226
227
228
229

230
231
232


233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257

258
259
260

261
262
263
264
265
266

267
268
269

270
271

272
273
274

275
276
277

278
279
280

281
282
283

284
285

286
287

288
289
290

291
292

293
294

295
296
297
298

299
300

301
302
303

304
305

306
307
308
309


310
311
312
313
314
315
316
103
104
105
106
107
108
109









110
111

112
113
114
115

116
117
118

119
120
121

122
123
124

125
126
127

128
129
130

131
132


133
134
135
136

137
138
139

140
141
142

143
144
145

146
147
148

149
150
151


152
153
154

155
156
157
158
159
160
161

162
163
164
165
166
167
168

169
170
171

172
173
174

175
176
177

178
179
180

181
182
183

184
185

186
187
188
189
190
191

192
193
194

195
196
197

198
199
200

201
202
203

204
205

206
207
208
209
210
211

212
213

214
215
216
217
218
219

220
221


222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247

248
249
250

251
252



253

254
255
256

257
258

259
260
261

262
263
264

265
266
267

268
269
270

271
272

273
274

275
276
277

278
279

280
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 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,
	DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorderPtr), -1,
	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_Offset(TkMenuEntry, activeFgPtr), -1, 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_Offset(TkMenuEntry, accelPtr), -1, 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_Offset(TkMenuEntry, borderPtr), -1, 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_Offset(TkMenuEntry, bitmapPtr), -1, 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},
	-1, Tk_Offset(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_Offset(TkMenuEntry, commandPtr), -1, 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},
	DEF_MENU_ENTRY_COMPOUND, -1, Tk_Offset(TkMenuEntry, compound), 0,
	tkCompoundStrings, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	DEF_MENU_ENTRY_FONT,
	offsetof(TkMenuEntry, fontPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
	Tk_Offset(TkMenuEntry, fontPtr), -1, 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_Offset(TkMenuEntry, fgPtr), -1, 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},
	-1, Tk_Offset(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_Offset(TkMenuEntry, imagePtr), -1, 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_Offset(TkMenuEntry, labelPtr), -1, 0, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, state), 0,
	(ClientData) menuStateStrings, 0},
	-1, Tk_Offset(TkMenuEntry, state),
	0, menuStateStrings, 0},
    {TK_OPTION_INT, "-underline", NULL, NULL,
	DEF_MENU_ENTRY_UNDERLINE, TCL_INDEX_NONE, offsetof(TkMenuEntry, underline), 0, NULL, 0},
	DEF_MENU_ENTRY_UNDERLINE, -1, Tk_Offset(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_Offset(TkMenuEntry, borderPtr), -1, 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},
	-1, Tk_Offset(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_Offset(TkMenuEntry, offValuePtr), -1, 0, NULL, 0},
    {TK_OPTION_STRING, "-onvalue", NULL, NULL,
	DEF_MENU_ENTRY_ON_VALUE,
	offsetof(TkMenuEntry, onValuePtr), TCL_INDEX_NONE, 0, NULL, 0},
	Tk_Offset(TkMenuEntry, onValuePtr), -1, 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_Offset(TkMenuEntry, indicatorFgPtr), -1, 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_Offset(TkMenuEntry, selectImagePtr), -1, 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_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
	NULL, 0, -1, 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},
	-1, Tk_Offset(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_Offset(TkMenuEntry, indicatorFgPtr), -1, 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_Offset(TkMenuEntry, selectImagePtr), -1, 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_Offset(TkMenuEntry, onValuePtr), -1, 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_Offset(TkMenuEntry, namePtr), -1, 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
	NULL, 0, -1, 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_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
	NULL, 0, -1, 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_Offset(TkMenuEntry, borderPtr), -1, 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},
	DEF_MENU_ENTRY_STATE, -1, Tk_Offset(TkMenuEntry, state),
	0, 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,
	Tk_Offset(TkMenu, activeBorderPtr), -1, 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_Offset(TkMenu, activeBorderWidthPtr), -1, 0, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground",
	"Background", DEF_MENU_ACTIVE_FG_COLOR,
	offsetof(TkMenu, activeFgPtr), TCL_INDEX_NONE, 0,
	Tk_Offset(TkMenu, activeFgPtr), -1, 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,
	DEF_MENU_BG_COLOR, Tk_Offset(TkMenu, borderPtr), -1, 0,
	(ClientData) DEF_MENU_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENU_BORDER_WIDTH,
	offsetof(TkMenu, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
	Tk_Offset(TkMenu, borderWidthPtr), -1, 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_Offset(TkMenu, cursorPtr), -1, 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,
	Tk_Offset(TkMenu, disabledFgPtr), -1, 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},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENU_FONT, offsetof(TkMenu, fontPtr), TCL_INDEX_NONE, 0, NULL, 0},
	DEF_MENU_FONT, Tk_Offset(TkMenu, fontPtr), -1, 0, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENU_FG, offsetof(TkMenu, fgPtr), TCL_INDEX_NONE, 0, NULL, 0},
	DEF_MENU_FG, Tk_Offset(TkMenu, fgPtr), -1, 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_Offset(TkMenu, postCommandPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENU_RELIEF, offsetof(TkMenu, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
	DEF_MENU_RELIEF, Tk_Offset(TkMenu, reliefPtr), -1, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background",
	DEF_MENU_SELECT_COLOR, offsetof(TkMenu, indicatorFgPtr), TCL_INDEX_NONE, 0,
	DEF_MENU_SELECT_COLOR, Tk_Offset(TkMenu, indicatorFgPtr), -1, 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_Offset(TkMenu, takeFocusPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff",
	DEF_MENU_TEAROFF, TCL_INDEX_NONE, offsetof(TkMenu, tearoff), 0, NULL, 0},
	DEF_MENU_TEAROFF, -1, Tk_Offset(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_Offset(TkMenu, tearoffCommandPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-title", "title", "Title",
	DEF_MENU_TITLE,	 offsetof(TkMenu, titlePtr), TCL_INDEX_NONE,
	DEF_MENU_TITLE,	 Tk_Offset(TkMenu, titlePtr), -1,
	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},
	DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypePtr), -1,
	0, 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.
 */
341
342
343
344
345
346
347
348
349


350
351

352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
329
330
331
332
333
334
335


336
337
338

339
340
341
342
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		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,
static Tcl_FreeProc	DestroyMenuEntry;
static int		GetIndexFromCoords(Tcl_Interp *interp,
			    TkMenu *menuPtr, const char *string,
			    TkSizeT *indexPtr);
			    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 void		MenuCmdDeletedProc(ClientData clientData);
static TkMenuEntry *	MenuNewEntry(TkMenu *menuPtr, TkSizeT index, int type);
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		MenuCleanup(ClientData unused);
static void		TkMenuCleanup(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.
 */

409
410
411
412
413
414
415

416

417
418
419
420
421
422
423
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410







+
-
+







    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;
    int i, index, toplevel;
    int 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 ...?");
455
456
457
458
459
460
461
462

463
464

465
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
442
443
444
445
446
447
448

449
450

451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467







-
+

-
+








-
+







    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->active = -1;
    menuPtr->cursorPtr = NULL;
    menuPtr->mainMenuPtr = menuPtr;
    menuPtr->masterMenuPtr = 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,
    if (Tk_InitOptions(interp, (char *) menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin)
	    != TCL_OK) {
    	Tk_DestroyWindow(menuPtr->tkwin);
    	return TCL_ERROR;
    }


522
523
524
525
526
527
528
529
530
531



532
533
534
535
536
537
538
509
510
511
512
513
514
515



516
517
518
519
520
521
522
523
524
525







-
-
-
+
+
+







	     * 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
     	    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]);
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590







-
+







    	    listtkwin = topLevelListPtr->tkwin;
    	    TkSetWindowMenuBar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(menuPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(menuPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuWidgetObjCmd --
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
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







-
+





-
+





-
+

-
+







	    sizeof(char *), "option", 0, &option) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(menuPtr);

    switch ((enum options) option) {
    case MENU_ACTIVATE: {
	TkSizeT index;
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	if (TkGetMenuIndex(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)
	if ((index >= 0) && ((menuPtr->entries[index]->type==SEPARATOR_ENTRY)
		|| (menuPtr->entries[index]->state == ENTRY_DISABLED))) {
	    index = TCL_INDEX_NONE;
	    index = -1;
	}
	result = TkActivateMenuEntry(menuPtr, index);
	break;
    }
    case MENU_ADD:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type ?-option value ...?");
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
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







-
+



















-
+









-
+

















-
+
-












-
+
-



-
+




-
+











-
+






-
+






-
+


-
+




-
+









-
+






-
+


-
+





-
+








-
+















-
+





-
+


-
+

-
-
+
+
+













-
+





-
+


-
+







-
+










-
+







    case MENU_CGET: {
	Tcl_Obj *resultPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}
	resultPtr = Tk_GetOptionValue(interp, menuPtr,
	resultPtr = Tk_GetOptionValue(interp, (char *) 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,
	    resultPtr = Tk_GetOptionInfo(interp, (char *) 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,
	    resultPtr = Tk_GetOptionInfo(interp, (char *) 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;
	int 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) {
		&& Tcl_GetIntFromObj(NULL, objv[2], &first) == TCL_OK) {
	    first = w;
	    if (first >= menuPtr->numEntries) {
		goto done;
	    }
	} else if (GetMenuIndex(interp,menuPtr,objv[2],0,&first) != TCL_OK){
	} else if (TkGetMenuIndex(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) {
	} 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 == TCL_INDEX_NONE) || (last < first)) {
	if ((first == -1) || (last < first)) {
	    goto done;
	}
	DeleteMenuCloneEntries(menuPtr, first, last);
	break;
    }
    case MENU_ENTRYCGET: {
	TkSizeT index;
	int 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) {
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	if (index < 0) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	resultPtr = Tk_GetOptionValue(interp, mePtr,
	resultPtr = Tk_GetOptionValue(interp, (char *) 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;
	int 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) {
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	if (index < 0) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, mePtr,
	    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, mePtr,
	    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(mePtr);
	break;
    }
    case MENU_INDEX: {
	TkSizeT index;
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	if (index < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
	} else
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(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;
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	if (index < 0) {
	    goto done;
	}
	result = TkInvokeMenu(interp, menuPtr, index);
	break;
    }
    case MENU_POST: {
	int x, y;
	TkSizeT index = TCL_INDEX_NONE;
	int index = -1;

	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) {
            if (TkGetMenuIndex(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
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
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







-
+






-
+


-
+







-
+






-
+


-
+







	    result = TkpPostMenu(interp, menuPtr, x, y, index);
	} else {
	    result = TkpPostTearoffMenu(interp, menuPtr, x, y, index);
	}
	break;
    }
    case MENU_POSTCASCADE: {
	TkSizeT index;
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}

	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if ((index == TCL_INDEX_NONE) || (menuPtr->entries[index]->type != CASCADE_ENTRY)) {
	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: {
	TkSizeT index;
	int 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) {
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	if (index < 0) {
	    goto done;
	}
	if (menuPtr->entries[index]->type == TEAROFF_ENTRY) {
	    typeStr = "tearoff";
	} else {
	    typeStr = menuEntryTypeStrings[menuPtr->entries[index]->type];
	}
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
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







-
+








+
+
+
+
-
+




+

-
+







+
+
+
+
+
+
+
+
+
+
+
-
+









-
+











-
+





-
+






-
+













-
-
-
-
+
+
+
+
-


+
-
+
+







 *	associated with that index.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Commands may get excecuted; variables may get set; sub-menus may get
 *	posted.
 *	posted, the passed menu may be destroyed.
 *
 *----------------------------------------------------------------------
 */

int
TkInvokeMenu(
    Tcl_Interp *interp,		/* The interp that the menu lives in. */
    TkMenu *menuPtr,		/* The menu we are invoking. */
				/* Must be protected by Tcl_Preserve
				 * against freeing by the caller.
				 * Tk Bug [2d3a81c0].
				 */
    TkSizeT index)			/* The zero based index of the item we are
    int index)			/* The zero based index of the item we are
    				 * invoking. */
{
    int result = TCL_OK;
    TkMenuEntry *mePtr;
    Tcl_Obj *commandPtr = NULL, *namePtr = NULL;

    if (index == TCL_INDEX_NONE) {
    if (index < 0) {
    	goto done;
    }
    mePtr = menuPtr->entries[index];
    if (mePtr->state == ENTRY_DISABLED) {
	goto done;
    }

    if (mePtr->commandPtr != NULL) {
	commandPtr = mePtr->commandPtr;
	Tcl_IncrRefCount(commandPtr);
    }
    if ((mePtr->type == CHECK_BUTTON_ENTRY) ||
	    (mePtr->type == RADIO_BUTTON_ENTRY)) {
	if (mePtr->namePtr != NULL) {
	    namePtr = mePtr->namePtr;
	    Tcl_IncrRefCount(namePtr);
	}
    }
    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)) {
	    && (namePtr != NULL)) {
	Tcl_Obj *valuePtr;

	if (mePtr->entryFlags & ENTRY_SELECTED) {
	    valuePtr = mePtr->offValuePtr;
	} else {
	    valuePtr = mePtr->onValuePtr;
	}
	if (valuePtr == NULL) {
	    valuePtr = Tcl_NewObj();
	}
	Tcl_IncrRefCount(valuePtr);
	if (Tcl_ObjSetVar2(interp, mePtr->namePtr, NULL, valuePtr,
	if (Tcl_ObjSetVar2(interp, namePtr, NULL, valuePtr,
		TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(valuePtr);
    } else if ((mePtr->type == RADIO_BUTTON_ENTRY)
	    && (mePtr->namePtr != NULL)) {
	    && (namePtr != NULL)) {
	Tcl_Obj *valuePtr = mePtr->onValuePtr;

	if (valuePtr == NULL) {
	    valuePtr = Tcl_NewObj();
	}
	Tcl_IncrRefCount(valuePtr);
	if (Tcl_ObjSetVar2(interp, mePtr->namePtr, NULL, valuePtr,
	if (Tcl_ObjSetVar2(interp, namePtr, NULL, valuePtr,
		TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(valuePtr);
    }

    /*
     * We check numEntries in addition to whether the menu entry has a command
     * because that goes to zero if the menu gets deleted (e.g., during
     * command evaluation).
     */

    if ((menuPtr->numEntries != 0) && (result == TCL_OK)
	    && (mePtr->commandPtr != NULL)) {
	Tcl_Obj *commandPtr = mePtr->commandPtr;

	Tcl_IncrRefCount(commandPtr);
	    && (commandPtr != NULL)) {
	result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL);
    }
    if (commandPtr != NULL) {
	result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL);
	Tcl_DecrRefCount(commandPtr);
    }
    if (namePtr != NULL) {
    Tcl_Release(mePtr);
	Tcl_DecrRefCount(namePtr);
    }

  done:
    return result;
}

/*
 *----------------------------------------------------------------------
1135
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145

1146
1147
1148
1149
1150
1151
1152
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147

1148
1149
1150
1151
1152
1153
1154
1155







-
+


-
+







    if (TkFreeMenuReferences(menuPtr->menuRefPtr)) {
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->mainMenuPtr != menuPtr) {
    	if (menuPtr->masterMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);

	    parentMainMenuPtr = cascadePtr->menuPtr->mainMenuPtr;
	    parentMainMenuPtr = cascadePtr->menuPtr->masterMenuPtr;
	    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
1161
1162
1163
1164
1165
1166
1167
1168
1169


1170
1171
1172
1173
1174
1175
1176
1164
1165
1166
1167
1168
1169
1170


1171
1172
1173
1174
1175
1176
1177
1178
1179







-
-
+
+







		Tcl_DecrRefCount(newObjv[1]);
	    }
    	} else {
    	    ConfigureMenuEntry(cascadePtr, 0, NULL);
    	}
    }

    if (menuPtr->mainMenuPtr != menuPtr) {
	for (menuInstancePtr = menuPtr->mainMenuPtr;
    if (menuPtr->masterMenuPtr != menuPtr) {
	for (menuInstancePtr = menuPtr->masterMenuPtr;
		menuInstancePtr != NULL;
		menuInstancePtr = menuInstancePtr->nextInstancePtr) {
	    if (menuInstancePtr->nextInstancePtr == menuPtr) {
		menuInstancePtr->nextInstancePtr =
			menuInstancePtr->nextInstancePtr->nextInstancePtr;
		break;
	    }
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
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







-
+


+


+

















-
-
-
-
-
+
+
+
+







	/*
	 * 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]);
	Tcl_EventuallyFree(menuPtr->entries[i], DestroyMenuEntry);
	menuPtr->numEntries = i;
    }
    menuPtr->active = -1;
    if (menuPtr->entries != NULL) {
	ckfree(menuPtr->entries);
	menuPtr->entries = NULL;
    }
    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.
 *	This function is invoked 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.
 *
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272
1273
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277







-
+







	topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;
	while (topLevelListPtr != NULL) {
	    nextTopLevelPtr = topLevelListPtr->nextPtr;
	    TkpSetWindowMenuBar(topLevelListPtr->tkwin, NULL);
	    topLevelListPtr = nextTopLevelPtr;
	}
    }
    if (menuPtr->mainMenuPtr == menuPtr) {
    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
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







-
+




















-
+



















-
+







 *	Everything associated with the menu entry is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuEntry(
    void *memPtr)		/* Pointer to entry to be freed. */
    char *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) {
	if (menuPtr->masterMenuPtr != 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->masterMenuPtr == destroyThis)) {
		    destroyThis = NULL;
		}
	    }
	    UnhookCascadeEntry(mePtr);
	    menuRefPtr = mePtr->childMenuRefPtr;
	    if (menuRefPtr != NULL) {
		if (menuRefPtr->menuPtr == destroyThis) {
1489
1490
1491
1492
1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1493
1494
1495
1496
1497
1498
1499

1500
1501
1502
1503
1504
1505
1506
1507







-
+







 */

static void
MenuWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)instanceData;
    TkSizeT i;
    int i;

    TkMenuConfigureDrawOptions(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	TkMenuConfigureEntryDrawOptions(menuPtr->entries[i],
		menuPtr->entries[i]->index);
	TkpConfigureMenuEntry(menuPtr->entries[i]);
    }
1533
1534
1535
1536
1537
1538
1539
1540

1541
1542
1543

1544
1545
1546
1547

1548
1549
1550
1551
1552
1553
1554
1537
1538
1539
1540
1541
1542
1543

1544
1545
1546

1547
1548
1549
1550

1551
1552
1553
1554
1555
1556
1557
1558







-
+


-
+



-
+







{
    int i;
    TkMenu *menuListPtr, *cleanupPtr;
    int result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	menuListPtr->errorStructPtr = (Tk_SavedOptions *)ckalloc(sizeof(Tk_SavedOptions));
	result = Tk_SetOptions(interp, menuListPtr,
	result = Tk_SetOptions(interp, (char *) menuListPtr,
		tsdPtr->menuOptionTable, objc, objv,
		menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
	if (result != TCL_OK) {
	    for (cleanupPtr = menuPtr->mainMenuPtr;
	    for (cleanupPtr = menuPtr->masterMenuPtr;
		    cleanupPtr != menuListPtr;
		    cleanupPtr = cleanupPtr->nextInstancePtr) {
		Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
		ckfree(cleanupPtr->errorStructPtr);
		cleanupPtr->errorStructPtr = NULL;
	    }
	    if (menuListPtr->errorStructPtr != NULL) {
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
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







-
+

















-
+

-
+


















-
+









-
+







	 * 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;
		    for (cleanupPtr = menuPtr->masterMenuPtr;
			    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);
	    Tcl_EventuallyFree(menuListPtr->entries[0], DestroyMenuEntry);

	    for (i = 0; i < (int)menuListPtr->numEntries - 1; i++) {
	    for (i = 0; i < 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++) {
	for (i = 0; i < menuListPtr->numEntries; i++) {
	    TkMenuEntry *mePtr;

	    mePtr = menuListPtr->entries[i];
	    ConfigureMenuEntry(mePtr, 0, NULL);
	}

	TkEventuallyRecomputeMenu(menuListPtr);
    }

    for (cleanupPtr = menuPtr->mainMenuPtr; cleanupPtr != NULL;
    for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != NULL;
	    cleanupPtr = cleanupPtr->nextInstancePtr) {
	Tk_FreeSavedOptions(cleanupPtr->errorStructPtr);
	ckfree(cleanupPtr->errorStructPtr);
	cleanupPtr->errorStructPtr = NULL;
    }

    return TCL_OK;
1706
1707
1708
1709
1710
1711
1712
1713

1714
1715
1716
1717
1718

1719
1720
1721
1722
1723
1724
1725
1710
1711
1712
1713
1714
1715
1716

1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
1729







-
+




-
+







     * 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);
	Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	(void)TkGetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
	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.
     */
1929
1930
1931
1932
1933
1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1933
1934
1935
1936
1937
1938
1939

1940
1941
1942
1943
1944
1945
1946
1947







-
+







	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,
	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
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







-
+











-










-
+







 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuCloneEntries(
    Tcl_Interp *dummy,		/* Used for error reporting. */
    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;
    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];
    mePtr = menuPtr->masterMenuPtr->entries[index];
    if (mePtr->type == CASCADE_ENTRY) {
	oldCascadePtr = mePtr->namePtr;
	if (oldCascadePtr != NULL) {
	    Tcl_IncrRefCount(oldCascadePtr);
	}
    }

2035
2036
2037
2038
2039
2040
2041
2042

2043
2044
2045
2046
2047
2048
2049
2038
2039
2040
2041
2042
2043
2044

2045
2046
2047
2048
2049
2050
2051
2052







-
+







	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	    cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    newCascadeName);
	}
    }

    for (menuListPtr = menuPtr->mainMenuPtr->nextInstancePtr;
    for (menuListPtr = menuPtr->masterMenuPtr->nextInstancePtr;
    	    menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = menuListPtr->entries[index];

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
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
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







-
+

















-
+







-
+


-
+
-
-
-
-
-
-
-
-
-
-
-
-



-
+


-
+
+

-
+


+
-
-
+
+
-
+



-
+

+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





-
+







-
-
-







    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * GetMenuIndex --
 * 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
GetMenuIndex(
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. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
    int *indexPtr)		/* Where to store converted index. */
{
    int i;
    const char *string;
    const char *string = Tcl_GetString(objPtr);

    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;
	return TCL_OK;
    }

    if ((string[0] == 'l') && (strcmp(string, "last") == 0)) {
    if (((string[0] == 'l') && (strcmp(string, "last") == 0))
	    || ((string[0] == 'e') && (strcmp(string, "end") == 0))) {
	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	goto success;
	return TCL_OK;
    }

    if ((string[0] == '\0') ||
    if ((string[0] == 'n') && (strcmp(string, "none") == 0)) {
	*indexPtr = TCL_INDEX_NONE;
	    ((string[0] == 'n') && (strcmp(string, "none") == 0))) {
	*indexPtr = -1;
	goto success;
	return TCL_OK;
    }

    if (string[0] == '@') {
	if (GetIndexFromCoords(NULL, menuPtr, string, indexPtr)
	if (GetIndexFromCoords(interp, menuPtr, string, indexPtr)
		== TCL_OK) {
	    return TCL_OK;
	}
    }
	    goto success;
	}
    }

    for (i = 0; i < (int)menuPtr->numEntries; i++) {

    if (isdigit(UCHAR(string[0]))) {
	if (Tcl_GetIntFromObj(interp, objPtr, &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;
	    return TCL_OK;
	}
	Tcl_ResetResult(interp);
    }

    for (i = 0; i < 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;
	    return TCL_OK;
	}
    }

    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;
}

/*
 *----------------------------------------------------------------------
 *
 * MenuCmdDeletedProc --
 *
2238
2239
2240
2241
2242
2243
2244
2245

2246
2247
2248
2249
2250
2251

2252
2253
2254
2255
2256
2257
2258
2245
2246
2247
2248
2249
2250
2251

2252
2253
2254
2255
2256
2257

2258
2259
2260
2261
2262
2263
2264
2265







-
+





-
+







 *
 *----------------------------------------------------------------------
 */

static TkMenuEntry *
MenuNewEntry(
    TkMenu *menuPtr,		/* Menu that will hold the new entry. */
    TkSizeT index,			/* Where in the menu the new entry is to
    int 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;
    int i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Create a new array of entries with an empty slot for the new entry.
     */

2298
2299
2300
2301
2302
2303
2304
2305

2306
2307
2308
2309
2310
2311
2312
2305
2306
2307
2308
2309
2310
2311

2312
2313
2314
2315
2316
2317
2318
2319







-
+







    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,
    if (Tk_InitOptions(menuPtr->interp, (char *) mePtr,
	    mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
	ckfree(mePtr);
	return NULL;
    }
    TkMenuInitializeEntryDrawingFields(mePtr);
    if (TkpMenuNewEntry(mePtr) != TCL_OK) {
	Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable,
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
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







-
+




-
+





-
+

-
+




















-
+








-
+

-
+


-
+
-







    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;
    int index;
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;

    if (indexPtr != NULL) {
	if (GetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) {
	if (TkGetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	index = menuPtr->numEntries;
    }
    if (index == TCL_INDEX_NONE) {
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad menu entry index \"%s\"", Tcl_GetString(indexPtr)));
		"bad 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;
    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;
	    TkSizeT i;
	    int i;

	    for (errorMenuPtr = menuPtr->mainMenuPtr;
	    for (errorMenuPtr = menuPtr->masterMenuPtr;
		    errorMenuPtr != NULL;
		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {
    		Tcl_EventuallyFree(errorMenuPtr->entries[index],
    		Tcl_EventuallyFree(errorMenuPtr->entries[index], DestroyMenuEntry);
    	    		(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;
2420
2421
2422
2423
2424
2425
2426
2427

2428
2429
2430
2431
2432
2433
2434
2426
2427
2428
2429
2430
2431
2432

2433
2434
2435
2436
2437
2438
2439
2440







-
+







    	 */

    	if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
    	    if ((mePtr->namePtr != NULL)
		    && (mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr =
			mePtr->childMenuRefPtr->menuPtr->mainMenuPtr;
			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;

2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2491
2492
2493
2494
2495
2496
2497


2498
2499
2500
2501
2502
2503
2504







-
-







    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.
	 */

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
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







-
-
+
+




-
+













-
+







 *
 *----------------------------------------------------------------------
 */

int
TkActivateMenuEntry(
    TkMenu *menuPtr,	/* Menu in which to activate. */
    TkSizeT index)			/* Index of entry to activate, or
				 * TCL_INDEX_NONE to deactivate all entries. */
    int index)			/* Index of entry to activate, or -1 to
				 * deactivate all entries. */
{
    TkMenuEntry *mePtr;
    int result = TCL_OK;

    if (menuPtr->active != TCL_INDEX_NONE) {
    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 != TCL_INDEX_NONE) {
    if (index >= 0) {
	mePtr = menuPtr->entries[index];
	mePtr->state = ENTRY_ACTIVE;
	TkEventuallyRedrawMenu(menuPtr, mePtr);
    }
    return result;
}

2689
2690
2691
2692
2693
2694
2695
2696


2697
2698
2699
2700
2701
2702
2703
2693
2694
2695
2696
2697
2698
2699

2700
2701
2702
2703
2704
2705
2706
2707
2708







-
+
+







CloneMenu(
    TkMenu *menuPtr,		/* The menu we are going to clone. */
    Tcl_Obj *newMenuNamePtr,	/* The name to give the new menu. */
    Tcl_Obj *newMenuTypePtr)	/* What kind of menu is this, a normal menu a
    				 * menubar, or a tearoff? */
{
    int returnResult;
    int menuType, i;
    int menuType;
    int i;
    TkMenuReferences *menuRefPtr;
    Tcl_Obj *menuDupCommandArray[4];

    if (newMenuTypePtr == NULL) {
	menuType = MAIN_MENU;
    } else {
	if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr,
2738
2739
2740
2741
2742
2743
2744
2745

2746
2747

2748
2749
2750
2751
2752




2753
2754
2755
2756
2757
2758
2759
2743
2744
2745
2746
2747
2748
2749

2750
2751

2752
2753




2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764







-
+

-
+

-
-
-
-
+
+
+
+







	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {
	    menuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->mainMenuPtr = menuPtr->mainMenuPtr;
	    newMenuPtr->masterMenuPtr = menuPtr->masterMenuPtr;
	} else {
	    TkMenu *mainMenuPtr;
	    TkMenu *masterMenuPtr;

	    mainMenuPtr = menuPtr->mainMenuPtr;
	    newMenuPtr->nextInstancePtr = mainMenuPtr->nextInstancePtr;
	    mainMenuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->mainMenuPtr = mainMenuPtr;
	    masterMenuPtr = menuPtr->masterMenuPtr;
	    newMenuPtr->nextInstancePtr = masterMenuPtr->nextInstancePtr;
	    masterMenuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->masterMenuPtr = masterMenuPtr;
	}

	/*
	 * 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.
2775
2776
2777
2778
2779
2780
2781
2782

2783
2784
2785
2786
2787
2788
2789
2780
2781
2782
2783
2784
2785
2786

2787
2788
2789
2790
2791
2792
2793
2794







-
+







	    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);
			    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,
2800
2801
2802
2803
2804
2805
2806
2807

2808
2809
2810
2811
2812
2813
2814
2805
2806
2807
2808
2809
2810
2811

2812
2813
2814
2815
2816
2817
2818
2819







-
+







	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++) {
	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,
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
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







-
+


-
+



-
-
+
+

-
+








static int
MenuDoXPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    TkSizeT index;
    int index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
    if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_ResetResult(interp);
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->x));
	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
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







-
+


-
+



-
-
+
+

-
+








static int
MenuDoYPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    TkSizeT index;
    int index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
    if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	goto error;
    }
    Tcl_ResetResult(interp);
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->y));
	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
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
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







-
+




-
+

-
+
+
















-
+



+
+
+












-
+







 *
 * Side effects:
 *	If int is invalid, interp's result will be set to NULL.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
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 *indexPtr)		/* The index of the item that matches. */
{
    int x, y, i;
    int x, y;
    int 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;
    }
    Tk_GetPixelsFromObj(interp, menuPtr->tkwin,
	menuPtr->borderWidthPtr, &borderwidth);
    if (*end == ',') {
	x = y;
	p = end + 1;
	y = strtol(p, &end, 0);
	if (end == p) {
	if ((end == p) || (*end != '\0')) {
	    goto error;
	}
    } else {
	if (*end != '\0') {
	    goto error;
	}
	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++) {
    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)
3022
3023
3024
3025
3026
3027
3028
3029

3030
3031
3032
3033
3034
3035
3036
3031
3032
3033
3034
3035
3036
3037

3038
3039
3040
3041
3042
3043
3044
3045







-
+







 *----------------------------------------------------------------------
 */

static void
RecursivelyDeleteMenu(
    TkMenu *menuPtr)		/* The menubar instance we are deleting. */
{
    TkSizeT i;
    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.
     */

3109
3110
3111
3112
3113
3114
3115
3116

3117
3118
3119
3120
3121
3122
3123
3118
3119
3120
3121
3122
3123
3124

3125
3126
3127
3128
3129
3130
3131
3132







-
+








	    Tcl_DecrRefCount(resultPtr);
	    resultPtr = Tcl_DuplicateObj(parentPtr);
	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", -1);
	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
	    intPtr = Tcl_NewWideIntObj(i);
	    intPtr = Tcl_NewIntObj(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))) {
3175
3176
3177
3178
3179
3180
3181
3182

3183
3184
3185
3186
3187
3188
3189
3184
3185
3186
3187
3188
3189
3190

3191
3192
3193
3194
3195
3196
3197
3198







-
+







	     */

	    if (menuRefPtr->menuPtr != NULL) {
		TkMenu *instancePtr;

		menuPtr = menuRefPtr->menuPtr;

		for (instancePtr = menuPtr->mainMenuPtr;
		for (instancePtr = menuPtr->masterMenuPtr;
			instancePtr != NULL;
			instancePtr = instancePtr->nextInstancePtr) {
		    if (instancePtr->menuType == MENUBAR
			    && instancePtr->parentTopLevelPtr == tkwin) {
			RecursivelyDeleteMenu(instancePtr);
			break;
		    }
3308
3309
3310
3311
3312
3313
3314
3315

3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3317
3318
3319
3320
3321
3322
3323

3324
3325


3326
3327
3328
3329
3330
3331
3332







-
+

-
-







 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuHashTable(
    ClientData clientData,	/* The menu hash table we are destroying. */
    Tcl_Interp *dummy)		/* The interpreter we are destroying. */
    Tcl_Interp *interp)		/* The interpreter we are destroying. */
{
    (void)dummy;

    Tcl_DeleteHashTable((Tcl_HashTable *)clientData);
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+


-
+

-
+









-
-
+
+

-
+









-
+














-
-
+
+

-
-







				 * 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;
    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	for (i = last; i >= first; i--) {
	    Tcl_EventuallyFree(menuListPtr->entries[i], (Tcl_FreeProc *) DestroyMenuEntry);
	    Tcl_EventuallyFree(menuListPtr->entries[i], DestroyMenuEntry);
	}
	for (i = last + 1; i < (int)menuListPtr->numEntries; i++) {
	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(menuListPtr->entries);
	    menuListPtr->entries = NULL;
	}
	if (((int)menuListPtr->active >= first)
		&& ((int)menuListPtr->active <= last)) {
	if ((menuListPtr->active >= first)
		&& (menuListPtr->active <= last)) {
	    menuListPtr->active = -1;
	} else if ((int)menuListPtr->active > last) {
	} else if (menuListPtr->active > last) {
	    menuListPtr->active -= numDeleted;
	}
	TkEventuallyRecomputeMenu(menuListPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MenuCleanup --
 * TkMenuCleanup --
 *
 *	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)
TkMenuCleanup(
    ClientData unused)
{
    (void)dummy;

    menusInitialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInit --
3608
3609
3610
3611
3612
3613
3614
3615

3616
3617
3618
3619
3620
3621
3622
3613
3614
3615
3616
3617
3618
3619

3620
3621
3622
3623
3624
3625
3626
3627







-
+







	    menusInitialized = 1;
	}

	/*
	 * Make sure we cleanup on finalize.
	 */

	TkCreateExitHandler((Tcl_ExitProc *) MenuCleanup, NULL);
	TkCreateExitHandler((Tcl_ExitProc *) TkMenuCleanup, NULL);
	Tcl_MutexUnlock(&menuMutex);
    }
    if (!tsdPtr->menusInitialized) {
	TkpMenuThreadInit();
	tsdPtr->menuOptionTable =
		Tk_CreateOptionTable(NULL, tkMenuConfigSpecs);
	tsdPtr->entryOptionTables[TEAROFF_ENTRY] =
Changes to generic/tkMenu.h.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkMenu.h --
 *
 *	Declarations shared among all of the files that implement menu
 *	widgets.
 *
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 * Copyright (c) 1996-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 _TKMENU
#define _TKMENU
60
61
62
63
64
65
66
67

68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
60
61
62
63
64
65
66

67
68
69
70

71
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 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
				 * 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. */
    TkSizeT accelLength;	/* Number of non-NULL characters in
    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
     */
259
260
261
262
263
264
265
266
267
268



269
270
271
272
273
274
275
259
260
261
262
263
264
265



266
267
268
269
270
271
272
273
274
275







-
-
-
+
+
+







    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 numEntries;		/* Number of elements in entries. */
    int active;			/* Index of active entry. -1 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" */

    /*
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361







-
+







				 * 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;
    struct TkMenu *masterMenuPtr;
    				/* 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. */
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
374
375
376
377
378
379
380

381
382
383
384
385
386
387







-







				 * 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.
 */
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
457
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







+
















-
+












+
+



-
+


-
+

















-
+







 * 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 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, TkSizeT index);
MODULE_SCOPE int	TkActivateMenuEntry(TkMenu *menuPtr, int 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 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,
			    TkSizeT index);
			    int index);
MODULE_SCOPE void	TkMenuConfigureDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE int	TkMenuConfigureEntryDrawOptions(
			    TkMenuEntry *mePtr, TkSizeT index);
			    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);
			    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.
 */
536
537
538
539
540
541
542
543

544
545
546
538
539
540
541
542
543
544

545
546
547
548







-
+



			    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);
			    int x, int y, int index);
MODULE_SCOPE void	TkpSetWindowMenuBar(Tk_Window tkwin, TkMenu *menuPtr);

#endif /* _TKMENU */
Changes to generic/tkMenuDraw.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkMenuDraw.c --
 *
 *	This module implements the platform-independent drawing and geometry
 *	calculations of menu widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenu.h"
294
295
296
297
298
299
300
301

302
303
304
305
306
307
308
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308







-
+







 *
 *----------------------------------------------------------------------
 */

int
TkMenuConfigureEntryDrawOptions(
    TkMenuEntry *mePtr,
    TkSizeT index)
    int index)
{
    XGCValues gcValues;
    GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
    unsigned long mask;
    Tk_Font tkfont;
    TkMenu *menuPtr = mePtr->menuPtr;

483
484
485
486
487
488
489
490

491
492
493
494
495
496
497
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497







-
+








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;
    int i;

    if (menuPtr->tkwin == NULL) {
	return;
    }
    if (mePtr != NULL) {
	mePtr->entryFlags |= ENTRY_NEEDS_REDISPLAY;
    } else {
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
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;
    TkMenu *menuPtr = 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
582
583
584
585
586
587
588

589






590
591
592
593
594
595
596







-
+
-
-
-
-
-
-







    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;
    TkMenuEntry *mePtr = 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);
    }
}
617
618
619
620
621
622
623
624

625
626
627
628

629
630
631
632
633
634
635
611
612
613
614
615
616
617

618
619
620


621
622
623
624
625
626
627
628







-
+


-
-
+







 *----------------------------------------------------------------------
 */

static void
DisplayMenu(
    ClientData clientData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenu *menuPtr = clientData;
    TkMenuEntry *mePtr;
    Tk_Window tkwin = menuPtr->tkwin;
    TkSizeT index;
    int strictMotif;
    int index, strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;
    int relief;

762
763
764
765
766
767
768
769

770
771
772
773
774
775
776
755
756
757
758
759
760
761

762
763
764
765
766
767
768
769







-
+







 */

void
TkMenuEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;
    TkMenu *menuPtr = 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) {
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
842
843
844
845
846
847
820
821
822
823
824
825
826

827






828
829
830
831
832
833
834







-
+
-
-
-
-
-
-







    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;
    TkMenu *menuPtr = ((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);
    }
}

950
951
952
953
954
955
956
957
958


959
960
961
962
963
964
965
937
938
939
940
941
942
943


944
945
946
947
948
949
950
951
952







-
-
+
+








	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);
	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
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 structure below defines menubutton class behavior by means of
 * procedures that can be invoked from generic window code.
 */

static const Tk_ClassProcs menubuttonClass = {
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68



69
70
71


72
73

74
75
76
77
78




79
80

81
82
83
84


85
86

87
88
89
90


91
92
93

94
95
96


97
98

99
100

101
102

103
104
105
106

107
108
109


110
111
112

113
114

115
116
117

118
119
120

121
122

123
124
125

126
127
128

129
130
131

132
133
134
135


136
137
138


139
140
141


142
143

144
145
146


147
148
149


150
151

152
153
154

155
156
157
158
159
160
161
32
33
34
35
36
37
38


















39
40
41
42
43
44


45
46
47
48



49
50
51
52


53
54
55

56
57




58
59
60
61
62

63
64
65


66
67
68

69
70
71


72
73
74
75

76
77


78
79
80

81
82

83
84

85
86
87
88

89
90


91
92
93
94

95
96

97
98
99

100
101
102

103
104

105
106
107

108
109
110

111
112
113

114
115
116


117
118
119


120
121
122


123
124
125

126
127


128
129
130


131
132
133

134
135
136

137
138
139
140
141
142
143
144







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-






-
-
+
+


-
-
-
+
+
+

-
-
+
+

-
+

-
-
-
-
+
+
+
+

-
+


-
-
+
+

-
+


-
-
+
+


-
+

-
-
+
+

-
+

-
+

-
+



-
+

-
-
+
+


-
+

-
+


-
+


-
+

-
+


-
+


-
+


-
+


-
-
+
+

-
-
+
+

-
-
+
+

-
+

-
-
+
+

-
-
+
+

-
+


-
+







 * is used together with the "enum direction" declaration in tkMenubutton.h.
 */

static const char *const directionStrings[] = {
    "above", "below", "flush", "left", "right", NULL
};

/*
 * The following table defines the legal values for the -state option. It is
 * used together with the "enum state" declaration in tkMenubutton.h.
 */

static const char *const stateStrings[] = {
    "active", "disabled", "normal", NULL
};

/*
 * The following table defines the legal values for the -compound option. It
 * is used with the "enum compound" declaration in tkMenuButton.h
 */

static const char *const compoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

/*
 * 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,
	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, TCL_INDEX_NONE,
	 offsetof(TkMenuButton, activeFg),
	 0, DEF_MENUBUTTON_ACTIVE_FG_MONO, 0},
	DEF_MENUBUTTON_ACTIVE_FG_COLOR, -1,
	Tk_Offset(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},
	DEF_MENUBUTTON_ANCHOR, -1,
	Tk_Offset(TkMenuButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENUBUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkMenuButton, normalBorder),
	DEF_MENUBUTTON_BG_COLOR, -1, Tk_Offset(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_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1,
	0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, -1,
	0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_MENUBUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkMenuButton, 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, TCL_INDEX_NONE,
	offsetof(TkMenuButton, borderWidth), 0, 0, 0},
	DEF_MENUBUTTON_BORDER_WIDTH, -1,
	Tk_Offset(TkMenuButton, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENUBUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkMenuButton, 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, TCL_INDEX_NONE, offsetof(TkMenuButton, direction),
	0, directionStrings, 0},
	DEF_MENUBUTTON_DIRECTION, -1, Tk_Offset(TkMenuButton, direction),
	TK_OPTION_ENUM_VAR, directionStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkMenuButton, disabledFg), TK_OPTION_NULL_OK,
	-1, Tk_Offset(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_SYNONYM, "-fg", "foreground", NULL, NULL, 0, -1,
	0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENUBUTTON_FONT, TCL_INDEX_NONE, offsetof(TkMenuButton, tkfont), 0, 0, 0},
	DEF_MENUBUTTON_FONT, -1, Tk_Offset(TkMenuButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENUBUTTON_FG, TCL_INDEX_NONE, offsetof(TkMenuButton, normalFg), 0, 0, 0},
	DEF_MENUBUTTON_FG, -1, Tk_Offset(TkMenuButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_MENUBUTTON_HEIGHT, TCL_INDEX_NONE, offsetof(TkMenuButton, heightString),
	DEF_MENUBUTTON_HEIGHT, -1, Tk_Offset(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},
	-1, Tk_Offset(TkMenuButton, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_MENUBUTTON_HIGHLIGHT, TCL_INDEX_NONE,
	offsetof(TkMenuButton, highlightColorPtr),	0, 0, 0},
	DEF_MENUBUTTON_HIGHLIGHT, -1,
	Tk_Offset(TkMenuButton, highlightColorPtr),	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH,
	TCL_INDEX_NONE, offsetof(TkMenuButton, highlightWidth), 0, 0, 0},
	-1, Tk_Offset(TkMenuButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_MENUBUTTON_IMAGE, TCL_INDEX_NONE, offsetof(TkMenuButton, imageString),
	DEF_MENUBUTTON_IMAGE, -1, Tk_Offset(TkMenuButton, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_MENUBUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkMenuButton, indicatorOn),
	DEF_MENUBUTTON_INDICATOR, -1, Tk_Offset(TkMenuButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MENUBUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkMenuButton, justify), 0, 0, 0},
	DEF_MENUBUTTON_JUSTIFY, -1, Tk_Offset(TkMenuButton, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_MENUBUTTON_MENU, TCL_INDEX_NONE, offsetof(TkMenuButton, menuName),
	DEF_MENUBUTTON_MENU, -1, Tk_Offset(TkMenuButton, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_MENUBUTTON_PADX, TCL_INDEX_NONE, offsetof(TkMenuButton, padX),
	DEF_MENUBUTTON_PADX, -1, Tk_Offset(TkMenuButton, padX),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_MENUBUTTON_PADY, TCL_INDEX_NONE, offsetof(TkMenuButton, padY),
	DEF_MENUBUTTON_PADY, -1, Tk_Offset(TkMenuButton, padY),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENUBUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkMenuButton, relief),
	DEF_MENUBUTTON_RELIEF, -1, Tk_Offset(TkMenuButton, relief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuButton, compound), 0,
	 compoundStrings, 0},
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkMenuButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_MENUBUTTON_STATE, TCL_INDEX_NONE, offsetof(TkMenuButton, state),
	0, stateStrings, 0},
	DEF_MENUBUTTON_STATE, -1, Tk_Offset(TkMenuButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENUBUTTON_TAKE_FOCUS, TCL_INDEX_NONE,
	offsetof(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0},
	DEF_MENUBUTTON_TAKE_FOCUS, -1,
	Tk_Offset(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MENUBUTTON_TEXT, TCL_INDEX_NONE, offsetof(TkMenuButton, text), 0, 0, 0},
	DEF_MENUBUTTON_TEXT, -1, Tk_Offset(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},
	DEF_MENUBUTTON_TEXT_VARIABLE, -1,
	Tk_Offset(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},
	DEF_MENUBUTTON_UNDERLINE, -1, Tk_Offset(TkMenuButton, underline),
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_MENUBUTTON_WIDTH, TCL_INDEX_NONE, offsetof(TkMenuButton, widthString),
	DEF_MENUBUTTON_WIDTH, -1, Tk_Offset(TkMenuButton, widthString),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_MENUBUTTON_WRAP_LENGTH, TCL_INDEX_NONE, offsetof(TkMenuButton, wrapLength),
	DEF_MENUBUTTON_WRAP_LENGTH, -1, Tk_Offset(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
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204

205
206
207
208
209
210
211







-
+







-







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenubuttonObjCmd(
    ClientData dummy,	/* NULL. */
    ClientData clientData,	/* 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;
    }

    /*
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310







-
+









-
+







    mbPtr->takeFocus = NULL;
    mbPtr->flags = 0;

    Tk_CreateEventHandler(mbPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MenuButtonEventProc, mbPtr);

    if (Tk_InitOptions(interp, mbPtr, optionTable, tkwin) != TCL_OK) {
    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_SetObjResult(interp, Tk_NewWindowObj(mbPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(mbPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonWidgetObjCmd --
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339







-
+







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;
    TkMenuButton *mbPtr = clientData;
    int result, index;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382

383
384
385
386
387
388
389
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371







-
+









-
+







    switch (index) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, mbPtr,
	objPtr = Tk_GetOptionValue(interp, (char *) 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,
	    objPtr = Tk_GetOptionInfo(interp, (char *) mbPtr,
		    mbPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    mbPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516







-
+








    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, mbPtr,
	    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.
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625







-
+







	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);
	    mbPtr->text = 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);
    }

671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
653
654
655
656
657
658
659

660
661
662
663
664
665
666
667







-
+







void
TkMenuButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    TkMenuButton *mbPtr = (TkMenuButton *)instanceData;
    TkMenuButton *mbPtr = 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
772
773
774
775
776
777
778
779

780
781
782
783
784
785
786
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768







-
+







 */

static void
MenuButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    TkMenuButton *mbPtr = 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.
831
832
833
834
835
836
837
838

839
840
841
842
843
844
845
813
814
815
816
817
818
819

820
821
822
823
824
825
826
827







-
+







 *----------------------------------------------------------------------
 */

static void
MenuButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    TkMenuButton *mbPtr = 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
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







+








-
+

-
+
-
-







 * 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. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    TkMenuButton *mbPtr = clientData;
    const char *value;
    size_t len;
    unsigned 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) {
921
922
923
924
925
926
927
928
929


930
931
932
933
934
935
936
902
903
904
905
906
907
908


909
910
911
912
913
914
915
916
917







-
-
+
+







    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);
    len = 1 + (unsigned) strlen(value);
    mbPtr->text = 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;
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976
977
978
979
980
981
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. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    TkMenuButton *mbPtr = 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;
	}
Changes to generic/tkMenubutton.h.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkMenubutton.h --
 *
 *	Declarations of types and functions used to implement the menubutton
 *	widget.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMENUBUTTON
#define _TKMENUBUTTON
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175







-
+







				 * whether the menubutton should show both an
				 * image and text, and, if so, how. */
    enum direction direction;	/* Direction for where to pop the menu. Valid
    				 * directions are "above", "below", "left",
    				 * "right", and "flush". "flush" means that
    				 * the upper left corner of the menubutton is
    				 * where the menu pops up. "above" and "below"
    				 * will attempt to pop the menu compleletly
    				 * will attempt to pop the menu completely
    				 * above or below the menu respectively.
    				 * "left" and "right" will pop the menu left
    				 * or right, and the active item will be next
    				 * to the button. */
    Tk_Cursor cursor;		/* Current cursor for window, or NULL. */
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
Changes to generic/tkMessage.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
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15


16
17
18
19
20
21
22
23
24









-
+





-
-
+
+







/*
 * tkMessage.c --
 *
 *	This module implements a message widgets for the Tk toolkit. A message
 *	widget displays a multi-line string in a window according to a
 *	particular aspect ratio.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Ajuba Solutions.
 * 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 "default.h"
#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
105
106
107
108
109
110
111

112
113

114
115

116
117
118

119
120

121
122


123
124
125

126
127
128

129
130

131
132

133
134


135
136
137

138
139
140


141
142
143

144
145


146
147
148


149
150
151

152
153

154
155
156

157
158

159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190







-
+

-
+

-
+


-
+

-
+

-
-
+
+

-
+


-
+

-
+

-
+

-
-
+
+

-
+


-
-
+
+

-
+

-
-
+
+

-
-
+
+

-
+

-
+


-
+

-
+


-
+




















-
+








/*
 * 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},
	 -1, Tk_Offset(Message, anchor), 0, 0, 0},
    {TK_OPTION_INT, "-aspect", "aspect", "Aspect", DEF_MESSAGE_ASPECT,
	 TCL_INDEX_NONE, offsetof(Message, aspect), 0, 0, 0},
	 -1, Tk_Offset(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_COLOR, -1, Tk_Offset(Message, border), 0,
	 DEF_MESSAGE_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-background", 0},
	 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_MESSAGE_BORDER_WIDTH, TCL_INDEX_NONE,
	 offsetof(Message, borderWidth), 0, 0, 0},
	 DEF_MESSAGE_BORDER_WIDTH, -1,
	 Tk_Offset(Message, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_MESSAGE_CURSOR, TCL_INDEX_NONE, offsetof(Message, cursor),
	 DEF_MESSAGE_CURSOR, -1, Tk_Offset(Message, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL,
	 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MESSAGE_FONT, TCL_INDEX_NONE, offsetof(Message, tkfont), 0, 0, 0},
	DEF_MESSAGE_FONT, -1, Tk_Offset(Message, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MESSAGE_FG, TCL_INDEX_NONE, offsetof(Message, fgColorPtr), 0, 0, 0},
	DEF_MESSAGE_FG, -1, Tk_Offset(Message, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, TCL_INDEX_NONE,
	 offsetof(Message, highlightBgColorPtr), 0, 0, 0},
	 "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, -1,
	 Tk_Offset(Message, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_MESSAGE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Message, highlightColorPtr),
	 DEF_MESSAGE_HIGHLIGHT, -1, Tk_Offset(Message, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MESSAGE_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Message, highlightWidth), 0, 0, 0},
	"HighlightThickness", DEF_MESSAGE_HIGHLIGHT_WIDTH, -1,
	 Tk_Offset(Message, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MESSAGE_JUSTIFY, TCL_INDEX_NONE, offsetof(Message, justify), 0, 0, 0},
	DEF_MESSAGE_JUSTIFY, -1, Tk_Offset(Message, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	 DEF_MESSAGE_PADX, offsetof(Message, padXPtr),
	 offsetof(Message, padX), 0, 0, 0},
	 DEF_MESSAGE_PADX, Tk_Offset(Message, padXPtr),
	 Tk_Offset(Message, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	 DEF_MESSAGE_PADY, offsetof(Message, padYPtr),
	 offsetof(Message, padY), 0, 0, 0},
	 DEF_MESSAGE_PADY, Tk_Offset(Message, padYPtr),
	 Tk_Offset(Message, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MESSAGE_RELIEF, TCL_INDEX_NONE, offsetof(Message, relief), 0, 0, 0},
	DEF_MESSAGE_RELIEF, -1, Tk_Offset(Message, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MESSAGE_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Message, 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, TCL_INDEX_NONE, offsetof(Message, string), 0, 0, 0},
	DEF_MESSAGE_TEXT, -1, Tk_Offset(Message, string), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MESSAGE_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Message, textVarName),
	DEF_MESSAGE_TEXT_VARIABLE, -1, Tk_Offset(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},
	DEF_MESSAGE_WIDTH, -1, Tk_Offset(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		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.
 */

210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246


247
248
249
250
251
252
253
210
211
212
213
214
215
216

217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243


244
245
246
247
248
249
250
251
252







-
+







-



















-
-
+
+







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MessageObjCmd(
    ClientData dummy,	/* NULL. */
    ClientData clientData,	/* 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));
    msgPtr = 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);
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287







-
+









-
+







    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) {
    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_SetObjResult(interp, Tk_NewWindowObj(msgPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(msgPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MessageWidgetObjCmd --
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316







-
+







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;
    Message *msgPtr = 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) {
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353







-
+











-
+








    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,
	    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, msgPtr,
	    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;
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392







-
+







 *	Everything associated with the message is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMessage(
    void *memPtr)		/* Info about message widget. */
    char *memPtr)		/* Info about message widget. */
{
    Message *msgPtr = (Message *) memPtr;

    msgPtr->flags |= MESSAGE_DELETED;

    Tcl_DeleteCommandFromToken(msgPtr->interp, msgPtr->widgetCmd);
    if (msgPtr->flags & REDRAW_PENDING) {
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465







-











-
+







    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,
    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
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
474
475
476
477
478
479
480

481
482
483
484
485
486
487
488







-
+







	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);
	    msgPtr->string = strcpy(ckalloc(strlen(value) + 1), value);
	}
	Tcl_TraceVar2(interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }

    /*
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
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 = (Message *)instanceData;
    Message *msgPtr = instanceData;

    if (msgPtr->border != NULL) {
	Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border);
    }

    gcValues.font = Tk_FontId(msgPtr->tkfont);
    gcValues.foreground = msgPtr->fgColorPtr->pixel;
664
665
666
667
668
669
670
671

672
673
674
675
676
677
678
662
663
664
665
666
667
668

669
670
671
672
673
674
675
676







-
+







 *--------------------------------------------------------------
 */

static void
DisplayMessage(
    ClientData clientData)	/* Information about window. */
{
    Message *msgPtr = (Message *)clientData;
    Message *msgPtr = 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;
740
741
742
743
744
745
746
747

748
749
750
751
752
753
754
738
739
740
741
742
743
744

745
746
747
748
749
750
751
752







-
+







 */

static void
MessageEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Message *msgPtr = (Message *)clientData;
    Message *msgPtr = 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) {
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
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;
    Message *msgPtr = 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
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







+








-
+

-
-







 *
 * 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. */
{
    Message *msgPtr = (Message *)clientData;
    Message *msgPtr = 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) {
881
882
883
884
885
886
887
888

889
890
891
892
893
894
895
878
879
880
881
882
883
884

885
886
887
888
889
890
891
892







-
+







    if (value == NULL) {
	value = "";
    }
    if (msgPtr->string != NULL) {
	ckfree(msgPtr->string);
    }
    msgPtr->numChars = Tcl_NumUtfChars(value, -1);
    msgPtr->string = (char *)ckalloc(strlen(value) + 1);
    msgPtr->string = 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;
Changes to generic/tkObj.c.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
45
46
47
48
49
50
51


52
53
54
55
56
57
58







-
-







 * 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.
 */

70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
68
69
70
71
72
73
74


75
76



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94























95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140







-
-
+

-
-
-


















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











-
+













-
+












-
+







 * 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
    long 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 */
    SetPixelFromAny		/* 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 */
    SetMMFromAny		/* 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 */
    SetWindowFromAny		/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * GetTypeCache --
 *
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
148
149
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 ThreadSpecificData *
GetTypeCache(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->doubleTypePtr == NULL) {
	/* Smart initialization of doubleTypePtr/intTypePtr without
	/* Smart initialization of doubleTypePtr 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
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
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 *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*/
	1.0,	10.0,	25.4,	0.35277777777777775 /*25.4 / 72.0*/
    };

    /*
     * Special hacks where the type of the object is known to be something
     * that is just numeric and cannot require distance conversion. This pokes
     * holes in Tcl's abstractions, but they are just for optimization, not
     * semantics.
     */

    if (objPtr->typePtr != &pixelObjType) {
	ThreadSpecificData *typeCache = GetTypeCache();

	if (objPtr->typePtr == typeCache->doubleTypePtr) {
	    (void) Tcl_GetDoubleFromObj(interp, objPtr, &d);
	if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
	    if (dblPtr != NULL) {
		*dblPtr = d;
	    }
	    *intPtr = (int) (d<0 ? d-0.5 : d+0.5);
	    return TCL_OK;
	} else if (objPtr->typePtr == typeCache->intTypePtr) {
	    (void) Tcl_GetIntFromObj(interp, objPtr, intPtr);
	    if (dblPtr) {
		*dblPtr = (double) (*intPtr);
	    }
	    return TCL_OK;
	}
    }

 retry:
    fresh = (objPtr->typePtr != &pixelObjType);
    if (fresh) {
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
427
428
429
430
431
432
433
434
435
436
437
438
439
440




441
442
443
444






445
446
447
448
449
450
451
452


453
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







+






-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 */

static int
SetPixelFromAny(
    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 i, units;

    string = Tcl_GetString(objPtr);

    d = strtod(string, &rest);
    if (rest == string) {
    if (objPtr->typePtr != typeCache->doubleTypePtr
	    && Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) {
	d = (double) units;
	units = -1;
	goto error;
    }
    while ((*rest != '\0') && isspace(UCHAR(*rest))) {
	rest++;
    }


	/*
	 * In the case of ints, we need to ensure that a valid string exists
	 * in order for int-but-not-string objects to be converted back to
	 * ints again from pixel obj types.
	 */

	(void) Tcl_GetString(objPtr);
    switch (*rest) {
    case '\0':
    } else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
	units = -1;
    } else {
	string = Tcl_GetString(objPtr);

	d = strtod(string, &rest);
	if (rest == string) {
	    goto error;
	}
	while ((*rest != '\0') && isspace(UCHAR(*rest))) {
	    rest++;
	}

	switch (*rest) {
	case '\0':
	    units = -1;
	break;
    case 'm':
	units = 0;
	break;
    case 'c':
	units = 1;
	break;
    case 'i':
	units = 2;
	break;
    case 'p':
	units = 3;
	break;
    default:
	goto error;
    }

	    break;
	case 'm':
	    units = 0;
	    break;
	case 'c':
	    units = 1;
	    break;
	case 'i':
	    units = 2;
	    break;
	case 'p':
	    units = 3;
	    break;
	default:
	    goto error;
	}
    }
    /*
     * Free the old internalRep before setting the new one.
     */

    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
633
634
635
636
637
638
639
640

641
642
643
644
645
646
647
545
546
547
548
549
550
551

552
553
554
555
556
557
558
559







-
+







    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*/
	10.0,	25.4,	1.0,	0.35277777777777775 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
747
748
749
750
751
752
753
754

755
756
757
758
759
760
761
659
660
661
662
663
664
665

666
667
668
669
670
671
672
673







-
+








static void
UpdateStringOfMM(
    Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    TkSizeT len;
    size_t 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");
    }

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
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







-
+





-
+
-
-
-
-
+










+
+









-
-
-
-
-







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 *string;
    char *rest;
    double d;
    int units;
    MMRep *mmPtr;

    if (objPtr->typePtr == typeCache->doubleTypePtr) {
    if (objPtr->typePtr != typeCache->doubleTypePtr
	Tcl_GetDoubleFromObj(interp, objPtr, &d);
	units = -1;
    } else if (objPtr->typePtr == typeCache->intTypePtr) {
	Tcl_GetIntFromObj(interp, objPtr, &units);
	    && Tcl_GetIntFromObj(NULL, objPtr, &units) == TCL_OK) {
	d = (double) units;
	units = -1;

	/*
	 * In the case of ints, we need to ensure that a valid string exists
	 * in order for int-but-not-string objects to be converted back to
	 * ints again from mm obj types.
	 */

	(void) Tcl_GetString(objPtr);
    } else if (Tcl_GetDoubleFromObj(NULL, objPtr, &d) == TCL_OK) {
	units = -1;
    } else {
	/*
	 * It wasn't a known int or double, so parse it.
	 */

	string = Tcl_GetString(objPtr);

	d = strtod(string, &rest);
	if (rest == string) {
	    /*
	     * Must copy string before resetting the result in case a caller
	     * is trying to convert the interpreter's result to mms.
	     */

	error:
	    Tcl_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))) {
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
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







-
+

-
-
+
+











-
+







    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_NewWindowObj --
 * TkNewWindowObj --
 *
 *	This function allocates a new Tcl_Obj that refers to a particular to a
 *	particular Tk window.
 *	This function allocates a new Tcl_Obj that refers to a particular
 *	Tk window.
 *
 * Results:
 *	A standard Tcl object reference, with refcount 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_NewWindowObj(
TkNewWindowObj(
    Tk_Window tkwin)
{
    Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    SetWindowFromAny(NULL, objPtr);
Changes to generic/tkOldConfig.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
10
11
12
13
14
15
16









17


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 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.
 */

#ifdef _WIN32
#define INIT		0x20

#include "tkWinInt.h"
#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);
			    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,
			    const Tk_ConfigSpec *specPtr, void *widgRec);
			    const Tk_ConfigSpec *specPtr, char *widgRec);
static const char *	FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, void *widgRec,
			    const 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);

/*
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99







-
+







    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);
	Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", (char *)NULL);
	return TCL_ERROR;
    }

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145







-
+







	/*
	 * Process the entry.
	 */

	if (argc < 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", arg));
	    Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", NULL);
	    Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", (char *)NULL);
	    return TCL_ERROR;
	}
	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetString((Tcl_Obj *) argv[1]);
	} else {
	    arg = argv[1];
	}
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302







-
+








-
+

















-
+







	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);
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, (char *)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);
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, (char *)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);
			(char *)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
368

369
370
371
372
373

374
375
376
377
378
379
380
381
382
383
384
385
386

387
388
389
390

391
392
393
394
395

396
397
398


399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432


433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451

452
453
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
329
330
331
332
333
334
335

336
337
338

339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359

360
361
362
363
364

365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382

383
384
385
386

387
388
389
390
391

392
393


394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

410
411
412
413

414
415
416
417
418
419
420
421
422
423
424
425
426
427


428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447

448
449
450
451
452
453
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







-
+


-
+




-
+



+
+
+
+
+

+
+
+
-
+


-
+




-
+




-
+












-
+



-
+




-
+

-
-
+
+














-
+



-
+













-
-
+
+














-
+



-
+














-
+



-
+




-
+
















-
+



-
+







-
+





-
+





-
+





-
+




-
+





-
+














-
+




-
+






-
+







    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.
    char *widgRec)		/* Record whose fields are to be modified.
				 * Values must be properly initialized. */
{
    void *ptr;
    char *ptr;
    Tk_Uid uid;
    int nullValue;

    nullValue = 0;
    if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) {
    if ((*value == 0) && (specPtr->specFlags & (TK_CONFIG_NULL_OK|32 /* TCL_NULL_OK */))) {
	nullValue = 1;
    }

    if (specPtr->specFlags & TK_CONFIG_OBJS) {
	/* Prevent surprises, TK_CONFIG_OBJS is not supported here in 8.6 */
	Tcl_AppendResult(interp, "TK_CONFIG_OBJS not supported", (char *)NULL);
	return TCL_ERROR;
    }
    do {
	if (specPtr->offset < 0) {
	    break;
	}
	ptr = (char *)widgRec + specPtr->offset;
	ptr = widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) {
	    if (Tcl_GetBoolean(interp, value, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_INT:
	    if (Tcl_GetInt(interp, value, (int *) ptr) != TCL_OK) {
	    if (Tcl_GetInt(interp, value, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_DOUBLE:
	    if (Tcl_GetDouble(interp, value, (double *) ptr) != TCL_OK) {
	    if (Tcl_GetDouble(interp, value, (double *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    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);
	    oldStr = *((char **)ptr);
	    if (oldStr != NULL) {
		ckfree(oldStr);
	    }
	    *((char **) ptr) = newStr;
	    *((char **)ptr) = newStr;
	    break;
	}
	case TK_CONFIG_UID:
	    if (nullValue) {
		*((Tk_Uid *) ptr) = NULL;
		*((Tk_Uid *)ptr) = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		*((Tk_Uid *) ptr) = uid;
		uid = valueIsUid ? (Tk_Uid)value : Tk_GetUid(value);
		*((Tk_Uid *)ptr) = uid;
	    }
	    break;
	case TK_CONFIG_COLOR: {
	    XColor *newPtr, *oldPtr;

	    if (nullValue) {
		newPtr = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newPtr = Tk_GetColor(interp, tkwin, uid);
		if (newPtr == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldPtr = *((XColor **) ptr);
	    oldPtr = *((XColor **)ptr);
	    if (oldPtr != NULL) {
		Tk_FreeColor(oldPtr);
	    }
	    *((XColor **) ptr) = newPtr;
	    *((XColor **)ptr) = newPtr;
	    break;
	}
	case TK_CONFIG_FONT: {
	    Tk_Font newFont;

	    if (nullValue) {
		newFont = NULL;
	    } else {
		newFont = Tk_GetFont(interp, tkwin, value);
		if (newFont == NULL) {
		    return TCL_ERROR;
		}
	    }
	    Tk_FreeFont(*((Tk_Font *) ptr));
	    *((Tk_Font *) ptr) = newFont;
	    Tk_FreeFont(*((Tk_Font *)ptr));
	    *((Tk_Font *)ptr) = newFont;
	    break;
	}
	case TK_CONFIG_BITMAP: {
	    Pixmap newBmp, oldBmp;

	    if (nullValue) {
		newBmp = None;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newBmp = Tk_GetBitmap(interp, tkwin, uid);
		if (newBmp == None) {
		    return TCL_ERROR;
		}
	    }
	    oldBmp = *((Pixmap *) ptr);
	    oldBmp = *((Pixmap *)ptr);
	    if (oldBmp != None) {
		Tk_FreeBitmap(Tk_Display(tkwin), oldBmp);
	    }
	    *((Pixmap *) ptr) = newBmp;
	    *((Pixmap *)ptr) = newBmp;
	    break;
	}
	case TK_CONFIG_BORDER: {
	    Tk_3DBorder newBorder, oldBorder;

	    if (nullValue) {
		newBorder = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newBorder = Tk_Get3DBorder(interp, tkwin, uid);
		if (newBorder == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldBorder = *((Tk_3DBorder *) ptr);
	    oldBorder = *((Tk_3DBorder *)ptr);
	    if (oldBorder != NULL) {
		Tk_Free3DBorder(oldBorder);
	    }
	    *((Tk_3DBorder *) ptr) = newBorder;
	    *((Tk_3DBorder *)ptr) = newBorder;
	    break;
	}
	case TK_CONFIG_RELIEF:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) {
	    if (Tk_GetRelief(interp, uid, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_CURSOR:
	case TK_CONFIG_ACTIVE_CURSOR: {
	    Tk_Cursor newCursor, oldCursor;

	    if (nullValue) {
		newCursor = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newCursor = Tk_GetCursor(interp, tkwin, uid);
		if (newCursor == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldCursor = *((Tk_Cursor *) ptr);
	    oldCursor = *((Tk_Cursor *)ptr);
	    if (oldCursor != NULL) {
		Tk_FreeCursor(Tk_Display(tkwin), oldCursor);
	    }
	    *((Tk_Cursor *) ptr) = newCursor;
	    *((Tk_Cursor *)ptr) = newCursor;
	    if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) {
		Tk_DefineCursor(tkwin, newCursor);
	    }
	    break;
	}
	case TK_CONFIG_JUSTIFY:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) {
	    if (Tk_GetJustify(interp, uid, (Tk_Justify *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_ANCHOR:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) {
	    if (Tk_GetAnchor(interp, uid, (Tk_Anchor *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_CAP_STYLE:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) {
	    if (Tk_GetCapStyle(interp, uid, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_JOIN_STYLE:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) {
	    if (Tk_GetJoinStyle(interp, uid, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_PIXELS:
	    if (Tk_GetPixels(interp, tkwin, value, (int *) ptr)
	    if (Tk_GetPixels(interp, tkwin, value, (int *)ptr)
		!= TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_MM:
	    if (Tk_GetScreenMM(interp, tkwin, value, (double*)ptr) != TCL_OK) {
	    if (Tk_GetScreenMM(interp, tkwin, value, (double *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_WINDOW: {
	    Tk_Window tkwin2;

	    if (nullValue) {
		tkwin2 = NULL;
	    } else {
		tkwin2 = Tk_NameToWindow(interp, value, tkwin);
		if (tkwin2 == NULL) {
		    return TCL_ERROR;
		}
	    }
	    *((Tk_Window *) ptr) = tkwin2;
	    *((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) {
		    interp, tkwin, value, 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);
	    Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", (char *)NULL);
	    return TCL_ERROR;
	}
	specPtr++;
    } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END));
    return TCL_OK;
}

652
653
654
655
656
657
658
659

660
661
662
663

664
665
666
667
668
669
670
649
650
651
652
653
654
655

656
657
658
659

660
661
662
663
664
665
666
667







-
+



-
+







	if ((argvName != NULL) && (specPtr->argvName != argvName)) {
	    continue;
	}
	if (((specPtr->specFlags & needFlags) != needFlags)
		|| (specPtr->specFlags & hateFlags)) {
	    continue;
	}
	if (specPtr->argvName == NULL) {
	if ((specPtr->argvName == NULL) || (specPtr->offset < 0)) {
	    continue;
	}
	list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
	Tcl_AppendResult(interp, leader, list, "}", NULL);
	Tcl_AppendResult(interp, leader, list, "}", (char *)NULL);
	ckfree(list);
	leader = " {";
    }
    return TCL_OK;
}

/*
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700







-
+







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
    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;

720
721
722
723
724
725
726
727
728


729
730

731
732
733
734
735
736
737
717
718
719
720
721
722
723


724
725
726

727
728
729
730
731
732
733
734







-
-
+
+

-
+







	argv[3] = "";
    }
    if (argv[4] == NULL) {
	argv[4] = "";
    }
    result = Tcl_Merge(5, argv);
    if (freeProc != NULL) {
	if ((freeProc == TCL_DYNAMIC) || (freeProc == (Tcl_FreeProc *) free)) {
	    ckfree((char *) argv[4]);
	if (freeProc == TCL_DYNAMIC) {
	    ckfree((char *)argv[4]);
	} else {
	    freeProc((char *) argv[4]);
	    freeProc((char *)argv[4]);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
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
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







-
+











+
+
+
-
+










-
+








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
    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. */
{
    void *ptr;
    const char *result;

    *freeProcPtr = NULL;
    if (specPtr->offset < 0) {
	return NULL;
    }
    ptr = (char *)widgRec + specPtr->offset;
    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));
	snprintf(buffer, 200, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_DOUBLE:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_STRING:
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
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







-
+















-
+







    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));
	snprintf(buffer, 200, "%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);
		tkwin, widgRec, specPtr->offset, freeProcPtr);
	break;
    default:
	result = "?? unknown type ??";
    }
    return result;
}

940
941
942
943
944
945
946
947
948


949
950

951
952
953
954
955
956
957
940
941
942
943
944
945
946


947
948
949

950
951
952
953
954
955
956
957







-
-
+
+

-
+







    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);
	if (freeProc == TCL_DYNAMIC) {
	    ckfree((char *)result);
	} else {
	    freeProc((char *) result);
	    freeProc((char *)result);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
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







+
+
+




-
-
-
+
+
+



-
-
-
+
+
+



-
-
+
+


-
-
-
+
+
+



-
-
-
+
+
+




-
-
-
+
+
+







{
    const Tk_ConfigSpec *specPtr;
    char *ptr;

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((specPtr->specFlags & needFlags) != needFlags) {
	    continue;
	}
	if (specPtr->offset < 0) {
	    continue;
	}
	ptr = widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_STRING:
	    if (*((char **) ptr) != NULL) {
		ckfree(*((char **) ptr));
		*((char **) ptr) = NULL;
	    if (*((char **)ptr) != NULL) {
		ckfree(*((char **)ptr));
		*((char **)ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_COLOR:
	    if (*((XColor **) ptr) != NULL) {
		Tk_FreeColor(*((XColor **) ptr));
		*((XColor **) ptr) = NULL;
	    if (*((XColor **)ptr) != NULL) {
		Tk_FreeColor(*((XColor **)ptr));
		*((XColor **)ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_FONT:
	    Tk_FreeFont(*((Tk_Font *) ptr));
	    *((Tk_Font *) ptr) = NULL;
	    Tk_FreeFont(*((Tk_Font *)ptr));
	    *((Tk_Font *)ptr) = NULL;
	    break;
	case TK_CONFIG_BITMAP:
	    if (*((Pixmap *) ptr) != None) {
		Tk_FreeBitmap(display, *((Pixmap *) ptr));
		*((Pixmap *) ptr) = None;
	    if (*((Pixmap *)ptr) != None) {
		Tk_FreeBitmap(display, *((Pixmap *)ptr));
		*((Pixmap *)ptr) = None;
	    }
	    break;
	case TK_CONFIG_BORDER:
	    if (*((Tk_3DBorder *) ptr) != NULL) {
		Tk_Free3DBorder(*((Tk_3DBorder *) ptr));
		*((Tk_3DBorder *) ptr) = NULL;
	    if (*((Tk_3DBorder *)ptr) != NULL) {
		Tk_Free3DBorder(*((Tk_3DBorder *)ptr));
		*((Tk_3DBorder *)ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_CURSOR:
	case TK_CONFIG_ACTIVE_CURSOR:
	    if (*((Tk_Cursor *) ptr) != NULL) {
		Tk_FreeCursor(display, *((Tk_Cursor *) ptr));
		*((Tk_Cursor *) ptr) = NULL;
	    if (*((Tk_Cursor *)ptr) != NULL) {
		Tk_FreeCursor(display, *((Tk_Cursor *)ptr));
		*((Tk_Cursor *)ptr) = NULL;
	    }
	}
    }
}

/*
 *--------------------------------------------------------------
Changes to generic/tkOldTest.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
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37










-
+















+
+
+
-
+







/*
 * tkOldTest.c --
 *
 *	This file contains C command functions for additional Tcl
 *	commands that are used to test Tk's support for legacy
 *	interfaces.  These commands are not normally included in Tcl/Tk
 *	applications; they're only used for testing.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 * Contributions by Don Porter, NIST, 2007.  (not subject to US copyright)
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#define USE_OLD_IMAGE
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif
#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. */
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







-
+







/*
 * 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
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179

180
181

182
183
184
185
186
187
188
106
107
108
109
110
111
112

113
114
115

116
117
118

119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178

179
180

181
182
183
184
185
186
187
188







-
+


-



-

-



















-
+
+

















-
















-
+




-
+

-
+







 *	Creates several test commands.
 *
 *----------------------------------------------------------------------
 */

int
TkOldTestInit(
    Tcl_Interp *dummy)
    Tcl_Interp *interp)
{
    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)

	/* 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_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 = ckalloc(sizeof(TImageModel));
    timPtr->model = model;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = (char *)ckalloc(strlen(name) + 1);
    timPtr->imageName = ckalloc(strlen(name) + 1);
    strcpy(timPtr->imageName, name);
    timPtr->varName = (char *)ckalloc(strlen(varName) + 1);
    timPtr->varName = 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;
}

199
200
201
202
203
204
205

206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221







+







-
+







 *
 * Side effects:
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
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;
    TImageModel *timPtr = 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) {
261
262
263
264
265
266
267
268

269
270
271
272
273

274
275
276
277

278
279
280
281
282
283
284
262
263
264
265
266
267
268

269
270
271
272
273

274
275
276
277

278
279
280
281
282
283
284
285







-
+




-
+



-
+








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;
    TImageModel *timPtr = clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    snprintf(buffer, sizeof(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 = 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;
}

308
309
310
311
312
313
314
315

316
317
318

319
320
321
322
323
324
325
309
310
311
312
313
314
315

316
317
318

319
320
321
322
323
324
325
326







-
+


-
+







    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;
    TImageInstance *instPtr = clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];

    sprintf(buffer, "%s display %d %d %d %d %d %d",
    snprintf(buffer, sizeof(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;
    }
353
354
355
356
357
358
359
360

361
362
363

364
365
366
367
368
369
370
354
355
356
357
358
359
360

361
362
363

364
365
366
367
368
369
370
371







-
+


-
+







 */

static void
ImageFree(
    ClientData clientData,	/* Pointer to TImageInstance for instance. */
    Display *display)		/* Display where image was to be drawn. */
{
    TImageInstance *instPtr = (TImageInstance *)clientData;
    TImageInstance *instPtr = clientData;
    char buffer[200];

    sprintf(buffer, "%s free", instPtr->modelPtr->imageName);
    snprintf(buffer, sizeof(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);
}

387
388
389
390
391
392
393
394

395
396
397

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
388
389
390
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
ImageDelete(
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageModel *timPtr = clientData;
    char buffer[100];

    sprintf(buffer, "%s delete", timPtr->imageName);
    snprintf(buffer, sizeof(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:
 */
Changes to generic/tkOption.c.
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
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







-
+












-
+







     * 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;
	size_t 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;
	classNameLength	= (size_t) (masqName - name);
	masqClass = (char *)ckalloc(classNameLength + 1);
	strncpy(masqClass, name, classNameLength);
	masqClass[classNameLength] = '\0';

	winClassId = Tk_GetUid(masqClass);
	ckfree(masqClass);
	winNameId = ((TkWindow *) tkwin)->nameUid;
1080
1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
1095
1080
1081
1082
1083
1084
1085
1086

1087

1088
1089
1090
1091
1092
1093
1094







-
+
-







    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;
    int result, bufferSize;
    TkSizeT bufferSize;
    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * Prevent file system access in a safe interpreter.
     */

1112
1113
1114
1115
1116
1117
1118
1119

1120
1121
1122
1123
1124
1125
1126
1111
1112
1113
1114
1115
1116
1117

1118
1119
1120
1121
1122
1123
1124
1125







-
+







	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) {
    if (bufferSize == -1) {
	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);
Changes to generic/tkPack.c.
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
116
117
118
119
120
121
122

123
124

125
126

127
128
129
130
131
132
133







-
+

-


-







/*
 * 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 Tcl_FreeProc	DestroyPacker;
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);

/*
159
160
161
162
163
164
165
166

167
168
169


170
171
172
173
174
175
176
157
158
159
160
161
162
163

164
165


166
167
168
169
170
171
172
173
174







-
+

-
-
+
+







    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));
		Tcl_NewIntObj(halfSpace));
    } else {
	padding[0] = Tcl_NewWideIntObj(halfSpace);
	padding[1] = Tcl_NewWideIntObj(allSpace - halfSpace);
	padding[0] = Tcl_NewIntObj(halfSpace);
	padding[1] = Tcl_NewIntObj(allSpace - halfSpace);
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1),
		Tcl_NewListObj(2, padding));
    }
}

/*
 *------------------------------------------------------------------------
195
196
197
198
199
200
201
202
203


204
205

206
207
208
209
210

211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228


229
230
231
232
233
234
235
236


237
238
239
240
241
242
243
244
245
246
247
248
249
250



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284



285
286
287
288
289
290
291
193
194
195
196
197
198
199


200
201


202


203


204


205
206
207
208
209
210
211
212
213
214
215
216
217
218
219


220
221
222
223
224
225
226
227


228
229
230
231
232
233
234

235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289







-
-
+
+
-
-
+
-
-

-
-
+
-
-
+














-
-
+
+






-
-
+
+





-







-
+
+
+
















-
+
+
+
















-
+
+
+







    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",
	/* after, append, before and unpack are deprecated */
	"after", "append", "before", "unpack", "configure",
#endif /* !TK_NO_DEPRECATED */
	"configure", "content", "forget", "info", "propagate", "slaves", NULL };
	"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,
	PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK, PACK_CONFIGURE,
#endif /* !TK_NO_DEPRECATED */
	PACK_CONFIGURE, PACK_CONTENT, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES };
	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) {
    if (Tcl_GetIndexFromObj(NULL, 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_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	Tcl_GetIndexFromObj(interp, objv[1], &optionStrings[4],
		"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 = GetPacker(tkwin2))) {
	    return TCL_OK;
	}
	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);
	if (!(containerPtr = GetPacker(tkwin2))) {
	    return TCL_OK;
	}
	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 = GetPacker(tkwin2))) {
	    return TCL_OK;
	}
	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;
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325



326
327
328
329
330
331
332
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
329
330
331







-

















-
+
+
+







		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 = GetPacker(content))) {
		continue;
	    }
	    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);
343
344
345
346
347
348
349
350



351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
342
343
344
345
346
347
348

349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368







-
+
+
+









-
+







	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 = GetPacker(content))) {
	    return TCL_OK;
	}
	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));
		TkNewWindowObj(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),
397
398
399
400
401
402
403
404



405
406
407
408
409
410
411
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412
413
414







-
+
+
+







	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 (!(containerPtr = GetPacker(container))) {
	    return TCL_OK;
	}
	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;
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
457
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







-
+
+
+



-
+




-












-
+










-







	    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);
	if (!(containerPtr = GetPacker(container))) {
	    return TCL_OK;
	}
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj(contentPtr->tkwin));
		    TkNewWindowObj(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)) {
	if (packPtr && (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;
}

/*
 *------------------------------------------------------------------------
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
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







-
+
+



-
+

















+
+
+
+








/*
 *------------------------------------------------------------------------
 *
 * GetPacker --
 *
 *	This internal function is used to locate a Packer structure for a
 *	given window, creating one if one doesn't exist already.
 *	window, creating one if one doesn't exist already, except if the window
 *	is already dead.
 *
 * Results:
 *	The return value is a pointer to the Packer structure corresponding to
 *	tkwin.
 *	tkwin, or NULL when tkwin is already dead.
 *
 * 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 (((TkWindow *) tkwin)->flags & TK_ALREADY_DEAD) {
	return NULL;
    }

    if (!dispPtr->packInit) {
	dispPtr->packInit = 1;
	Tcl_InitHashTable(&dispPtr->packerHashTable, TCL_ONE_WORD_KEYS);
    }

    /*
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114







-







 * 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. */
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
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







-
+











-
+
+
+


















-
-
+
+







	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]),
			"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);
	if (!(packPtr = GetPacker(tkwin))) {
	    return TCL_OK;
	}

	/*
	 * Process options for this window.
	 */

	if (Tcl_ListObjGetElements(interp, objv[1], &optionCount, &options)
		!= TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr->side = TOP;
	packPtr->anchor = TK_ANCHOR_CENTER;
	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);
	    int length;
	    const char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length);

	    c = curOpt[0];

	    if ((c == 't')
		    && (strncmp(curOpt, "top", length)) == 0) {
		packPtr->side = TOP;
	    } else if ((c == 'b')
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
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







-
+

















-
+












-
+







		    && (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)) {
		if (optionCount <= (index+1)) {
		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;
		}
		packPtr->padX /= 2;
		packPtr->padLeft /= 2;
		packPtr->iPadX = 0;
		index++;
	    } else if ((c == 'p') && (strcmp(curOpt, "pady")) == 0) {
		if (optionCount < (index+2)) {
		if (optionCount <= (index+1)) {
		    goto missingPad;
		}
		if (TkParsePadAmount(interp, tkwin, options[index+1],
			&packPtr->padTop, &packPtr->padY) != TCL_OK) {
		    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)) {
		if (optionCount <= (index+1)) {
		    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;
		}
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1323
1324
1325
1326
1327
1328
1329

1330
1331
1332
1333
1334
1335
1336







-







    }
    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.
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1376
1377
1378
1379
1380
1381
1382



1383
1384
1385
1386
1387

1388
1389
1390
1391
1392
1393
1394







-
-
-





-







    }

    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);
    }

}

/*
 *----------------------------------------------------------------------
 *
1401
1402
1403
1404
1405
1406
1407
1408

1409
1410
1411
1412



1413
1414
1415
1416
1417
1418
1419
1405
1406
1407
1408
1409
1410
1411

1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426







-
+




+
+
+







 *	Everything associated with the packer is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyPacker(
    void *memPtr)		/* Info about packed window that is now
    char *memPtr)		/* Info about packed window that is now
				 * dead. */
{
    Packer *packPtr = (Packer *)memPtr;

    if (packPtr->flags & REQUESTED_REPACK) {
	Tcl_CancelIdleCall(ArrangePacking, packPtr);
    }
    ckfree(packPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PackStructureProc --
1468
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482

1483
1484
1485
1486
1487
1488
1489
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496







-
+






-
+







	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}

	if (packPtr->tkwin != NULL) {
	    TkDisplay *dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr;
            Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable,
		    packPtr->tkwin));
		    (void *)packPtr->tkwin));
	}

	if (packPtr->flags & REQUESTED_REPACK) {
	    Tcl_CancelIdleCall(ArrangePacking, packPtr);
	}
	packPtr->tkwin = NULL;
	Tcl_EventuallyFree(packPtr, (Tcl_FreeProc *) DestroyPacker);
	Tcl_EventuallyFree(packPtr, 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)
1580
1581
1582
1583
1584
1585
1586
1587




1588
1589
1590
1591
1592
1593
1594
1587
1588
1589
1590
1591
1592
1593

1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604







-
+
+
+
+







	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);
	if (!(contentPtr = GetPacker(content))) {
	    continue;
	}

	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).
	 */
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
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







-
-
+
+










-
+
+
+







	    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) {
	    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 = GetPacker(other))) {
			continue;
		    }
		    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);
1644
1645
1646
1647
1648
1649
1650
1651



1652
1653
1654
1655
1656
1657
1658
1656
1657
1658
1659
1660
1661
1662

1663
1664
1665
1666
1667
1668
1669
1670
1671
1672







-
+
+
+







		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 = GetPacker(other))) {
			continue;
		    }
		    if (otherPtr->containerPtr == NULL) {
			goto notPacked;
		    }
		    containerPtr = otherPtr->containerPtr;
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr == otherPtr) {
			prevPtr = NULL;
1693
1694
1695
1696
1697
1698
1699
1700



1701
1702
1703
1704
1705
1706
1707
1707
1708
1709
1710
1711
1712
1713

1714
1715
1716
1717
1718
1719
1720
1721
1722
1723







-
+
+
+







		break;
	    case CONF_IN:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    containerPtr = GetPacker(other);
		    if (!(containerPtr = GetPacker(other))) {
			continue;
		    }
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr != NULL) {
			while (prevPtr->nextPtr != NULL) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
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







-
-
+
+







	    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) {
		if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames,
			"side", TCL_EXACT, &side) != TCL_OK) {
		    return TCL_ERROR;
		}
		contentPtr->side = (Side) side;
		break;
	    }
	}

1776
1777
1778
1779
1780
1781
1782
1783



1784
1785
1786
1787
1788
1789
1790
1792
1793
1794
1795
1796
1797
1798

1799
1800
1801
1802
1803
1804
1805
1806
1807
1808







-
+
+
+







	/*
	 * 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));
	    if (!(containerPtr = GetPacker(Tk_Parent(content)))) {
		continue;
	    }
	    prevPtr = containerPtr->contentPtr;
	    if (prevPtr != NULL) {
		while (prevPtr->nextPtr != NULL) {
		    prevPtr = prevPtr->nextPtr;
		}
	    }
	}
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
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







-
+







-
+












-
+







	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]),
			"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])));
		    "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",
		    "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;
Changes to generic/tkPanedWindow.c.
221
222
223
224
225
226
227
228

229
230
231

232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
221
222
223
224
225
226
227

228
229
230

231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+


-
+







-
+







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 internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetSticky(ClientData clientData, Tk_Window tkwin,
			    char *recordPtr, TkSizeT internalOffset);
			    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 *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 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 panes
 */

271
272
273
274
275
276
277
278
279


280
281

282
283

284
285
286


287
288
289


290
291
292


293
294
295


296
297
298


299
300
301


302
303
304


305
306
307


308
309
310


311
312
313


314
315

316
317
318


319
320
321


322
323
324


325
326
327


328
329
330


331
332
333


334
335
336
337
338
339
340


341
342
343


344
345
346


347
348

349
350

351
352

353
354

355
356
357


358
359
360


361
362
363


364
365
366
367
368
369
370
271
272
273
274
275
276
277


278
279
280

281
282

283
284


285
286
287


288
289
290


291
292
293


294
295
296


297
298
299


300
301
302


303
304
305


306
307
308


309
310
311


312
313
314

315
316


317
318
319


320
321
322


323
324
325


326
327
328


329
330
331


332
333
334
335
336
337
338


339
340
341


342
343
344


345
346
347

348
349

350
351

352
353

354
355


356
357
358


359
360
361


362
363
364
365
366
367
368
369
370







-
-
+
+

-
+

-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+

-
-
+
+





-
-
+
+

-
-
+
+

-
-
+
+

-
+

-
+

-
+

-
+

-
-
+
+

-
-
+
+

-
-
+
+







    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},
	DEF_PANEDWINDOW_BG_COLOR, -1, Tk_Offset(PanedWindow, background), 0,
	DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_PANEDWINDOW_BORDERWIDTH, TCL_INDEX_NONE, offsetof(PanedWindow, borderWidth),
	 0, 0, GEOMETRY},
	DEF_PANEDWINDOW_BORDERWIDTH, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_CURSOR, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_HANDLEPAD, -1, Tk_Offset(PanedWindow, handlePad),
	0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-handlesize", "handleSize", "HandleSize",
	 DEF_PANEDWINDOW_HANDLESIZE, offsetof(PanedWindow, handleSizePtr),
	 offsetof(PanedWindow, handleSize), 0, 0, GEOMETRY},
	DEF_PANEDWINDOW_HANDLESIZE, Tk_Offset(PanedWindow, handleSizePtr),
	Tk_Offset(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},
	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, TCL_INDEX_NONE,
	 offsetof(PanedWindow, resizeOpaque), 0, 0, 0},
	DEF_PANEDWINDOW_OPAQUERESIZE, -1,
	Tk_Offset(PanedWindow, resizeOpaque), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	 DEF_PANEDWINDOW_ORIENT, TCL_INDEX_NONE, offsetof(PanedWindow, orient),
	 0, orientStrings, GEOMETRY},
	DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient),
	TK_OPTION_ENUM_VAR, 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},
	0, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_PROXYBORDER, Tk_Offset(PanedWindow, proxyBorderWidthPtr),
	Tk_Offset(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief",
	 0, TCL_INDEX_NONE, offsetof(PanedWindow, proxyRelief),
	 TK_OPTION_NULL_OK, 0, 0},
	0, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_RELIEF, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_SASHCURSOR, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_SASHPAD, -1, Tk_Offset(PanedWindow, sashPad),
	0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-sashrelief", "sashRelief", "Relief",
	 DEF_PANEDWINDOW_SASHRELIEF, TCL_INDEX_NONE, offsetof(PanedWindow, sashRelief),
	 0, 0, 0},
	DEF_PANEDWINDOW_SASHRELIEF, -1, Tk_Offset(PanedWindow, sashRelief),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-sashwidth", "sashWidth", "Width",
	 DEF_PANEDWINDOW_SASHWIDTH, offsetof(PanedWindow, sashWidthPtr),
	 offsetof(PanedWindow, sashWidth), 0, 0, GEOMETRY},
	DEF_PANEDWINDOW_SASHWIDTH, Tk_Offset(PanedWindow, sashWidthPtr),
	Tk_Offset(PanedWindow, sashWidth), 0, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-showhandle", "showHandle", "ShowHandle",
	 DEF_PANEDWINDOW_SHOWHANDLE, TCL_INDEX_NONE, offsetof(PanedWindow, showHandle),
	 0, 0, GEOMETRY},
	DEF_PANEDWINDOW_SHOWHANDLE, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_WIDTH, Tk_Offset(PanedWindow, widthPtr),
	Tk_Offset(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},
	DEF_PANEDWINDOW_PANE_AFTER, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_PANE_BEFORE, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_PANE_HEIGHT, Tk_Offset(Pane, heightPtr),
	Tk_Offset(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},
	DEF_PANEDWINDOW_PANE_HIDE, -1, Tk_Offset(Pane, hide), 0,0,GEOMETRY},
    {TK_OPTION_PIXELS, "-minsize", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_MINSIZE, TCL_INDEX_NONE, offsetof(Pane, minSize), 0, 0, 0},
	DEF_PANEDWINDOW_PANE_MINSIZE, -1, Tk_Offset(Pane, minSize), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADX, TCL_INDEX_NONE, offsetof(Pane, padx), 0, 0, 0},
	DEF_PANEDWINDOW_PANE_PADX, -1, Tk_Offset(Pane, padx), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_PADY, TCL_INDEX_NONE, offsetof(Pane, pady), 0, 0, 0},
	DEF_PANEDWINDOW_PANE_PADY, -1, Tk_Offset(Pane, pady), 0, 0, 0},
    {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_STICKY, TCL_INDEX_NONE, offsetof(Pane, sticky), 0,
	 &stickyOption, 0},
	DEF_PANEDWINDOW_PANE_STICKY, -1, Tk_Offset(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},
	DEF_PANEDWINDOW_PANE_STRETCH, -1, Tk_Offset(Pane, stretch),
	TK_OPTION_ENUM_VAR, stretchStrings, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL,
	 DEF_PANEDWINDOW_PANE_WIDTH, offsetof(Pane, widthPtr),
	 offsetof(Pane, width), TK_OPTION_NULL_OK, 0, 0},
	DEF_PANEDWINDOW_PANE_WIDTH, Tk_Offset(Pane, widthPtr),
	Tk_Offset(Pane, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
 * Tk_PanedWindowObjCmd --
406
407
408
409
410
411
412
413

414
415
416
417

418
419
420
421
422
423
424
406
407
408
409
410
411
412

413
414
415
416

417
418
419
420
421
422
423
424







-
+



-
+








    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
	 * a pointer to the tables as the command's clientData so we'll have
	 * easy access to it in the future.
	 */

	pwOpts = (OptionTables *)ckalloc(sizeof(OptionTables));
	pwOpts = ckalloc(sizeof(OptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
	 */

	Tcl_SetAssocData(interp, "PanedWindowOptionTables",
		DestroyOptionTables, pwOpts);
455
456
457
458
459
460
461
462

463
464
465
466
467
468
469
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469







-
+







    /*
     * 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,
    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, pwPtr);
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516







-
+








    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));
    Tcl_SetObjResult(interp, TkNewWindowObj(pwPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowWidgetObjCmd --
547
548
549
550
551
552
553
554

555
556
557
558
559
560
561
547
548
549
550
551
552
553

554
555
556
557
558
559
560
561







-
+







    };
    Tcl_Obj *resultObj;
    int index, count, i, x, y;
    Tk_Window tkwin;
    Pane *panePtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	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;
    }
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
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







-
+











-
+








    case PW_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
	}
	resultObj = Tk_GetOptionValue(interp, pwPtr,
	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, pwPtr,
	    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);
	    }
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
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







-
+



















-
+



















-
+



















-
+







	    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,
			(char *) 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 ...?");
		    "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->numPanes; i++) {
		if (pwPtr->panes[i]->tkwin == tkwin) {
		    resultObj = Tk_GetOptionInfo(interp,
			    pwPtr->panes[i], pwPtr->paneOpts,
			    (char *) 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));
		    TkNewWindowObj(pwPtr->panes[i]->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case PW_PROXY:
	result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
	break;
843
844
845
846
847
848
849
850

851
852
853
854
855
856
857
843
844
845
846
847
848
849

850
851
852
853
854
855
856
857







-
+







     * 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,
    if (Tk_SetOptions(interp, (char *) &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
920
921
922
923
924
925
926
927

928
929
930
931
932
933
934
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934







-
+








	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],
		Tk_SetOptions(interp, (char *) 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;

967
968
969
970
971
972
973
974

975
976

977
978
979
980
981
982
983
967
968
969
970
971
972
973

974
975

976
977
978
979
980
981
982
983







-
+

-
+







	/*
	 * 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,
	Tk_InitOptions(interp, (char *)panePtr, pwPtr->paneOpts,
		pwPtr->tkwin);
	Tk_SetOptions(interp, panePtr, pwPtr->paneOpts,
	Tk_SetOptions(interp, (char *)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;
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
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







+
+

+
-
-
-
+
+
+
+


















-
+







    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.
	 * Be careful about the case pwPtr->numPanes == 0 since in this case
	 * pwPtr->panes is NULL, and the memcpy would have undefined behavior.
	 */
	if (pwPtr->numPanes) {
	memcpy((void *)&(newPanes[0]), pwPtr->panes,
		sizeof(Pane *) * pwPtr->numPanes);
	memcpy((void *)&(newPanes[pwPtr->numPanes]), inserts,
	    memcpy(newPanes, pwPtr->panes,
		    sizeof(Pane *) * pwPtr->numPanes);
	}
	memcpy(&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);
	memcpy(&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++;
	    }
1127
1128
1129
1130
1131
1132
1133
1134
1135


1136
1137
1138
1139
1140
1141
1142
1131
1132
1133
1134
1135
1136
1137


1138
1139
1140
1141
1142
1143
1144
1145
1146







-
-
+
+







	    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);
	coords[0] = Tcl_NewIntObj(panePtr->sashx);
	coords[1] = Tcl_NewIntObj(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;
1161
1162
1163
1164
1165
1166
1167
1168
1169


1170
1171
1172
1173
1174
1175
1176
1165
1166
1167
1168
1169
1170
1171


1172
1173
1174
1175
1176
1177
1178
1179
1180







-
-
+
+







	    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);
	    coords[0] = Tcl_NewIntObj(pwPtr->panes[sash]->markx);
	    coords[1] = Tcl_NewIntObj(pwPtr->panes[sash]->marky);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	}
	break;

    case SASH_DRAGTO:
    case SASH_PLACE:
	if (objc != 6) {
1244
1245
1246
1247
1248
1249
1250
1251

1252
1253
1254
1255
1256
1257
1258
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, pwPtr, pwPtr->optionTable, objc, objv,
    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);

2392
2393
2394
2395
2396
2397
2398
2399

2400
2401
2402
2403
2404
2405
2406
2396
2397
2398
2399
2400
2401
2402

2403
2404
2405
2406
2407
2408
2409
2410







-
+







 */

static Tcl_Obj *
GetSticky(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    TkSizeT internalOffset)		/* Offset within *recordPtr containing the
    int internalOffset)		/* Offset within *recordPtr containing the
				 * sticky value. */
{
    int sticky = *(int *)(recordPtr + internalOffset);
    char buffer[5];
    char *p = &buffer[0];

    if (sticky & STICK_NORTH) {
2444
2445
2446
2447
2448
2449
2450
2451

2452
2453
2454
2455
2456
2457
2458

2459
2460
2461
2462
2463
2464
2465
2448
2449
2450
2451
2452
2453
2454

2455
2456
2457
2458
2459
2460


2461
2462
2463
2464
2465
2466
2467
2468







-
+





-
-
+







    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
    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;
    void *internalPtr;
    char c, *internalPtr;
    const char *string;

    internalPtr = ComputeSlotAddress(recordPtr, internalOffset);

    if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
	*value = NULL;
    } else {
2872
2873
2874
2875
2876
2877
2878
2879
2880


2881
2882
2883
2884
2885
2886
2887
2875
2876
2877
2878
2879
2880
2881


2882
2883
2884
2885
2886
2887
2888
2889
2890







-
-
+
+







    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);
	coords[0] = Tcl_NewIntObj(pwPtr->proxyx);
	coords[1] = Tcl_NewIntObj(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;
3015
3016
3017
3018
3019
3020
3021
3022

3023
3024
3025


3026
3027
3028


3029
3030
3031
3032
3033
3034
3035
3018
3019
3020
3021
3022
3023
3024

3025
3026


3027
3028
3029


3030
3031
3032
3033
3034
3035
3036
3037
3038







-
+

-
-
+
+

-
-
+
+







 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void *
static char *
ComputeSlotAddress(
    void *recordPtr,	/* Pointer to the start of a record. */
    TkSizeT offset)		/* Offset of a slot within that record; may be TCL_INDEX_NONE. */
    char *recordPtr,	/* Pointer to the start of a record. */
    int offset)		/* Offset of a slot within that record; may be < 0. */
{
    if (offset != TCL_INDEX_NONE) {
	return (char *)recordPtr + offset;
    if (offset >= 0) {
	return recordPtr + offset;
    } else {
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------
3137
3138
3139
3140
3141
3142
3143
3144

3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3140
3141
3142
3143
3144
3145
3146

3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160







-
+













     * 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[0] = Tcl_NewIntObj(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:
 */
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.
77
78
79
80
81
82
83
84
85
86
87
88
89
90







91
92
93

94
95
96

97
98
99
100
101
102
103
104
105
106
107
108











109
110
111
112
113
114
115
77
78
79
80
81
82
83







84
85
86
87
88
89
90
91
92

93
94
95

96
97











98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115







-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
+


-
+

-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+







/*
 * 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),
    {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", -1,
	 Tk_Offset(Content, anchor), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", -1,
	 Tk_Offset(Content, borderMode), TK_OPTION_ENUM_VAR, borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", Tk_Offset(Content, heightPtr),
	 Tk_Offset(Content, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", -1, Tk_Offset(Content, inTkwin),
	 0, 0, IN_MASK},
    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
	 offsetof(Content, relHeightPtr), offsetof(Content, relHeight),
	 Tk_Offset(Content, relHeightPtr), Tk_Offset(Content, relHeight),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
	 offsetof(Content, relWidthPtr), offsetof(Content, relWidth),
	 Tk_Offset(Content, relWidthPtr), Tk_Offset(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}
    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", -1,
	 Tk_Offset(Content, relX), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", -1,
	 Tk_Offset(Content, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", Tk_Offset(Content, widthPtr),
	 Tk_Offset(Content, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", Tk_Offset(Content, xPtr),
	 Tk_Offset(Content, x), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", Tk_Offset(Content, yPtr),
	 Tk_Offset(Content, y), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * Flag definitions for Content structures:
 *
 * CHILD_WIDTH -		1 means -width was specified;
 * CHILD_REL_WIDTH -		1 means -relwidth was specified.
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139







-
+







/*
 * 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
    struct Content *contentPtr;	/* First in linked list of content placed
				 * 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. */
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
212
213
214
215
216
217
218



219
220
221
222
223
224
225







-
-
-







    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;
    }
246
247
248
249
250
251
252
253
254


255
256
257
258
259
260
261
243
244
245
246
247
248
249


250
251
252
253
254
255
256
257
258







-
-
+
+








	/*
	 * 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);
	    Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	    dispPtr->placeInit = 1;
	}

	return ConfigureContent(interp, tkwin, optionTable, objc-2, objv+2);
    }

    /*
270
271
272
273
274
275
276
277
278


279
280
281
282
283


284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
267
268
269
270
271
272
273


274
275
276
277
278


279
280








281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300







-
-
+
+



-
-
+
+
-
-
-
-
-
-
-
-












-
+








    /*
     * 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);
	Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
    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_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,
	    objPtr = Tk_GetOptionInfo(interp, (char *)contentPtr, optionTable,
		    (objc == 4) ? objv[3] : NULL, tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
321
322
323
324
325
326
327
328
329


330
331
332
333
334
335
336
310
311
312
313
314
315
316


317
318
319
320
321
322
323
324
325







-
-
+
+







	    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));
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
		(void *)tkwin));
	Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
		contentPtr);
	Tk_ManageGeometry(tkwin, NULL, NULL);
	Tk_UnmapWindow(tkwin);
	FreeContent(contentPtr);
	break;

352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355







-
+







	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));
			TkNewWindowObj(contentPtr->tkwin));
	    }
	    Tcl_SetObjResult(interp, listPtr);
	}
	break;
    }
    }

390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393







-
+







    Tk_OptionTable table)
{
    Tcl_HashEntry *hPtr;
    Content *contentPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->contentTable, (char *) tkwin, &isNew);
    hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (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.
433
434
435
436
437
438
439



440
441
442
443
444
445
446
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438







+
+
+







 *----------------------------------------------------------------------
 */

static void
FreeContent(
    Content *contentPtr)
{
    if (contentPtr->containerPtr && (contentPtr->containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	Tcl_CancelIdleCall(RecomputePlacement, contentPtr->containerPtr);
    }
    Tk_FreeConfigOptions((char *) contentPtr, contentPtr->optionTable,
	    contentPtr->tkwin);
    ckfree(contentPtr);
}

/*
 *----------------------------------------------------------------------
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469







-
+







static Content *
FindContent(
    Tk_Window tkwin)		/* Token for desired content. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->contentTable, tkwin);
    hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Content *)Tcl_GetHashValue(hPtr);
}

/*
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
495
496
497
498
499
500
501

502
503
504
505
506
507
508
509







-
+







	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");
		Tcl_Panic("UnlinkContent couldn't find slave to unlink");
	    }
	    if (prevPtr->nextPtr == contentPtr) {
		prevPtr->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550







-
+







    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);
    hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (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);
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592







-
+







static Container *
FindContainer(
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->containerTable, tkwin);
    hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Container *)Tcl_GetHashValue(hPtr);
}

/*
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
629
630
631
632
633
634
635

636
637
638
639
640
641
642
643







-
+







		"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,
    if (Tk_SetOptions(interp, (char *)contentPtr, table, objc, objv,
	    contentPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }

    /*
     * Set content flags. First clear the field, then add bits as needed.
     */
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
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







-
+







-
+













-
+








	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\"",
			"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",
		    "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",
		    "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;
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820







-
+







    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));
		TkNewWindowObj(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);
1111
1112
1113
1114
1115
1116
1117
1118
1119


1120
1121
1122
1123
1124
1125
1126
1103
1104
1105
1106
1107
1108
1109


1110
1111
1112
1113
1114
1115
1116
1117
1118







-
-
+
+







    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));
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable,
		(char *) containerPtr->tkwin));
	if (containerPtr->flags & PARENT_RECONFIG_PENDING) {
	    Tcl_CancelIdleCall(RecomputePlacement, containerPtr);
	}
	containerPtr->tkwin = NULL;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
1178
1179
1180
1181
1182
1183
1184
1185
1186


1187
1188
1189
1190
1191
1192
1193
1170
1171
1172
1173
1174
1175
1176


1177
1178
1179
1180
1181
1182
1183
1184
1185







-
-
+
+







    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));
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
		(char *) contentPtr->tkwin));
	FreeContent(contentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
1261
1262
1263
1264
1265
1266
1267
1268
1269


1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1253
1254
1255
1256
1257
1258
1259


1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273







-
-
+
+












    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));
    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
	    (char *) tkwin));
    Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
	    contentPtr);
    FreeContent(contentPtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkPlatDecls.h.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * tkPlatDecls.h --
 *
 *	Declarations of functions in the platform-specific public Tcl API.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * 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.
 */

#ifndef _TKPLATDECLS
#define _TKPLATDECLS
50
51
52
53
54
55
56
57
58
59
60













61
62
63
64

65
66
67
68


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104




105
106

107
108

109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
50
51
52
53
54
55
56




57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110




111
112
113
114
115

116
117

118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+



-
+
+















-
+
















-
-
-
-
+
+
+
+

-
+

-
+








-
+







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 */
/* 0 */
EXTERN void		Tk_MacOSXSetEmbedHandler(
				Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
				Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
				Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
				Tk_MacOSXEmbedGetClipProc *getClipProc,
				Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc);
/* 1 */
EXTERN void		Tk_MacOSXTurnOffMenus(void);
/* 2 */
EXTERN void		Tk_MacOSXTkOwnsCursor(int tkOwnsIt);
/* 3 */
EXTERN void		TkMacOSXInitMenus(Tcl_Interp *interp);
/* 4 */
EXTERN void		TkMacOSXInitAppleEvents(Tcl_Interp *interp);
/* 5 */
EXTERN void		TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y,
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 */
/* 7 */
EXTERN void *		TkMacOSXGetDrawablePort(Drawable drawable);
/* 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,
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 (*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 (*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 * (*tkMacOSXGetDrawablePort) (Drawable drawable); /* 7 */
    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 */
    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
}
141
142
143
144
145
146
147
148
149
150
151








152
153
154
155


156
157
158


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174


175
176
177
178
179
180
181
151
152
153
154
155
156
157




158
159
160
161
162
163
164
165
166
167


168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187


188
189
190
191
192
193
194
195
196







-
-
-
-
+
+
+
+
+
+
+
+


-
-
+
+


-
+
+














-
-
+
+







	(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 Tk_MacOSXSetEmbedHandler \
	(tkPlatStubsPtr->tk_MacOSXSetEmbedHandler) /* 0 */
#define Tk_MacOSXTurnOffMenus \
	(tkPlatStubsPtr->tk_MacOSXTurnOffMenus) /* 1 */
#define Tk_MacOSXTkOwnsCursor \
	(tkPlatStubsPtr->tk_MacOSXTkOwnsCursor) /* 2 */
#define TkMacOSXInitMenus \
	(tkPlatStubsPtr->tkMacOSXInitMenus) /* 3 */
#define TkMacOSXInitAppleEvents \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */
#define TkGenWMConfigureEvent_ \
	(tkPlatStubsPtr->tkGenWMConfigureEvent_) /* 5 */
#define TkGenWMConfigureEvent \
	(tkPlatStubsPtr->tkGenWMConfigureEvent) /* 5 */
#define TkMacOSXInvalClipRgns \
	(tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */
/* Slot 7 is reserved */
#define TkMacOSXGetDrawablePort \
	(tkPlatStubsPtr->tkMacOSXGetDrawablePort) /* 7 */
#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 */
#define TkGenWMConfigureEvent_ \
	(tkPlatStubsPtr->tkGenWMConfigureEvent_) /* 16 */
#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#ifdef __cplusplus
Changes to generic/tkPointer.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
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30








-
+













+







/*
 * tkPointer.c --
 *
 *	This file contains functions for emulating the X server pointer and
 *	grab state machine. This file is used by the Mac and Windows platforms
 *	to generate appropriate enter/leave events, and to update the global
 *	grab window information.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * 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.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#define Cursor XCursor
#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. */
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







static int
GenerateEnterLeave(
    TkWindow *winPtr,		/* Current Tk window (or NULL). */
    int x, int y,		/* Current mouse position in root coords. */
    int state)			/* State flags. */
{
    int crossed = 0;		/* 1 if mouse crossed a window boundary */
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    TkWindow *restrictWinPtr = tsdPtr->restrictWinPtr;
    TkWindow *lastWinPtr = tsdPtr->lastWinPtr;

    if (winPtr != tsdPtr->lastWinPtr) {
	if (restrictWinPtr) {
	    int newPos, oldPos;
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192







-
+







		XEvent event;

		/*
		 * Generate appropriate Enter/Leave events.
		 */

		InitializeEvent(&event, targetPtr, LeaveNotify, x, y, state,
			NotifyNormal);
			NotifyAncestor);

		TkInOutEvents(&event, lastWinPtr, winPtr, LeaveNotify,
			EnterNotify, TCL_QUEUE_TAIL);
		crossed = 1;
	    }
	}
	tsdPtr->lastWinPtr = winPtr;
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229







-
+







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. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    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;
250
251
252
253
254
255
256
257
258


259
260
261
262
263
264
265
251
252
253
254
255
256
257


258
259
260
261
262
263
264
265
266







-
-
+
+







    }

    /*
     * 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);
    for (b = Button1; b <= Button5; b++) {
	mask = TkGetButtonMask(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.
382
383
384
385
386
387
388
389

390
391
392
393
394
395
396
383
384
385
386
387
388
389

390
391
392
393
394
395
396
397







-
+







	    targetWinPtr = tsdPtr->restrictWinPtr;
	} else if (tsdPtr->grabWinPtr && !winPtr) {
	    targetWinPtr = tsdPtr->grabWinPtr;
	}

	if (targetWinPtr != NULL) {
	    InitializeEvent(&event, targetWinPtr, MotionNotify, x, y,
		    tsdPtr->lastState, NotifyNormal);
		    tsdPtr->lastState, NotifyAncestor);
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
	}
	tsdPtr->lastPos = pos;
    }
}

/*
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
421
422
423
424
425
426
427

428
429







430

431
432
433
434
435
436
437
438







-
+

-
-
-
-
-
-
-

-
+







    unsigned int event_mask,
    int pointer_mode,
    int keyboard_mode,
    Window confine_to,
    Cursor cursor,
    Time time)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    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++;
    LastKnownRequestProcessed(display)++;
    tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window);
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(tsdPtr->grabWinPtr);
    if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr)
	    != TK_GRAB_IN_TREE) {
	UpdateCursor(tsdPtr->grabWinPtr);
    }
462
463
464
465
466
467
468
469

470
471
472
473

474
475
476
477
478
479
480
456
457
458
459
460
461
462

463
464

465

466
467
468
469
470
471
472
473







-
+

-

-
+







 */

int
XUngrabPointer(
    Display *display,
    Time time)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)time;

    display->request++;
    LastKnownRequestProcessed(display)++;
    tsdPtr->grabWinPtr = NULL;
    tsdPtr->restrictWinPtr = NULL;
    TkpSetCapture(NULL);
    UpdateCursor(tsdPtr->lastWinPtr);
    return Success;
}

494
495
496
497
498
499
500
501

502
503
504
505

506
507
508
509
510
511
512
487
488
489
490
491
492
493

494
495
496
497

498
499
500
501
502
503
504
505







-
+



-
+







 *----------------------------------------------------------------------
 */

void
TkPointerDeadWindow(
    TkWindow *winPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr == tsdPtr->lastWinPtr) {
	tsdPtr->lastWinPtr = NULL;
	tsdPtr->lastWinPtr = TkGetContainer(winPtr);
    }
    if (winPtr == tsdPtr->grabWinPtr) {
	tsdPtr->grabWinPtr = NULL;
    }
    if (winPtr == tsdPtr->restrictWinPtr) {
	tsdPtr->restrictWinPtr = NULL;
    }
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548







-
+







 */

static void
UpdateCursor(
    TkWindow *winPtr)
{
    Cursor cursor = None;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * A window inherits its cursor from its parent if it doesn't have one of
     * its own. Top level windows inherit the default cursor.
     */

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
580
581
582
583
584
585
586

587
588

589
590
591
592

593
594
595
596
597
598
599
600
601
602
603







-
+

-




-
+










int
XDefineCursor(
    Display *display,
    Window w,
    Cursor cursor)
{
    TkWindow *winPtr = (TkWindow *) Tk_IdToWindow(display, w);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)cursor;

    if (tsdPtr->cursorWinPtr == winPtr) {
	UpdateCursor(winPtr);
    }
    display->request++;
    LastKnownRequestProcessed(display)++;
    return Success;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkRectOval.c.
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67

68
69

70
71

72
73
74

75
76

77
78
79

80
81
82

83
84
85

86
87
88

89
90

91
92
93

94
95
96
97
98



99
100
101

102
103

104
105
106

107
108

109
110
111

112
113

114
115

116
117
118
119

120
121
122
123
124
125
126
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66

67
68

69
70

71
72
73

74
75

76
77
78

79
80
81

82
83
84

85
86
87

88
89

90
91
92

93
94
95



96
97
98
99
100

101
102

103
104
105

106
107

108
109
110

111
112

113
114

115
116
117
118

119
120
121
122
123
124
125
126







-
+













-
+


-
+

-
+

-
+


-
+

-
+


-
+


-
+


-
+


-
+

-
+


-
+


-
-
-
+
+
+


-
+

-
+


-
+

-
+


-
+

-
+

-
+



-
+







 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, 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),
	NULL, Tk_Offset(RectOvalItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(RectOvalItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(RectOvalItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(RectOvalItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.activeStipple),
	NULL, Tk_Offset(RectOvalItem, outline.activeStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(RectOvalItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(RectOvalItem, outline.activeWidth),
	"0.0", Tk_Offset(RectOvalItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.dash),
	NULL, Tk_Offset(RectOvalItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(RectOvalItem, outline.offset),
	"0", Tk_Offset(RectOvalItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledDash),
	NULL, Tk_Offset(RectOvalItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(RectOvalItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(RectOvalItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledColor),
	NULL, Tk_Offset(RectOvalItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, outline.disabledStipple),
	NULL, Tk_Offset(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),
	NULL, Tk_Offset(RectOvalItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(RectOvalItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(RectOvalItem, fillColor), TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(RectOvalItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(RectOvalItem, tsoffset),
	"0,0", Tk_Offset(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},
	DEF_CANVITEM_OUTLINE, Tk_Offset(RectOvalItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(RectOvalItem, outline.tsoffset),
	"0,0", Tk_Offset(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},
	NULL, Tk_Offset(RectOvalItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state),TK_CONFIG_NULL_OK, &stateOption},
	NULL, Tk_Offset(Tk_Item, state),TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(RectOvalItem, fillStipple),TK_CONFIG_NULL_OK, NULL},
	NULL, Tk_Offset(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),
	"1.0", Tk_Offset(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:
 */
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
145
146
147
148
149
150
151


152
153
154
155
156
157
158







-
-







			    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);

/*
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
177
178
179
180
181
182
183


184
185
186
187
188
189
190
191







-
-
+







    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateRectOval,		/* rotateProc */
    0, NULL, NULL
    NULL, 0, NULL, NULL
};

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
201
202
203
204
205
206
207


208
209
210
211
212
213
214
215







-
-
+







    TranslateRectOval,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateRectOval,		/* rotateProc */
    0, NULL, NULL
    NULL, 0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateRectOval --
 *
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
571
572
573
574
575
576
577

578
579
580
581
582
583
584







-







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);
618
619
620
621
622
623
624

625
626
627
628
629
630
631
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627







+







 *
 * 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;
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
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







-
-
-
-













-
-
-
-
-
-
+
+
+
+
+
+

-
-
+
+

-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
-
-
-
-
+
+
+
+
+
+

-
-
+
+

-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+







				/* 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.
         */
	/*
	 * 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]);
	short ix1 = (short) (rectOvalPtr->bbox[0]);
	short ix2 = (short) (rectOvalPtr->bbox[2]);

        if (ix1 == ix2) {
	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.
             */
	    /*
	     * 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 {
	    if (ix1 > 0) {
		x2 += 1;
	    } else {
		x1 -= 1;
	    }
	} else {

            /*
             * (x1,x2) span two pixels. Select the one with the larger
             * covered "area".
             */
	    /*
	     * (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 (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.
         */
	/*
	 * 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]);
	short iy1 = (short) (rectOvalPtr->bbox[1]);
	short iy2 = (short) (rectOvalPtr->bbox[3]);

        if (iy1 == iy2) {
	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.
             */
	    /*
	     * 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 {
	    if (iy1 > 0) {
		y2 += 1;
	    } else {
		y1 -= 1;
	    }
	} else {

            /*
             * (y1,y2) span two pixels. Select the one with the larger
             * covered "area".
             */
	    /*
	     * (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;
                }
            }
        }
	    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.
     */
961
962
963
964
965
966
967

968
969
970
971
972
973
974
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967







+







 *
 * 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;
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087







+







 *
 * 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;
1134
1135
1136
1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142







+







 *
 * 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. */
{
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216







+







 *
 * 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. */
{
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
1278
1279
1280
1281
1282
1283
1284



















































1285
1286
1287
1288
1289
1290
1291







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







		&& ((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.
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1387
1388
1389
1390
1391
1392
1393

1394
1395
1396
1397
1398
1399
1400







-







    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.
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
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







-
+
+
+






-
+
+
+


















-
+
+
+
+












+
+
+
+
+
+









     * First draw the filled area of the rectangle.
     */

    if (fillColor != NULL) {
	Tcl_AppendObjToObj(psObj, pathObj);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fillColor);
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
		goto error;
	    }
	    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);
	if (Tk_CanvasPsOutline(canvas, itemPtr,
		&rectOvalPtr->outline)!= TCL_OK) {
	    goto error;
	}
	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;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    Tcl_DecrRefCount(pathObj);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkScale.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
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19



20
21
22
23


24
25
26
27
28
29
30
31
32
33
34
35
36









37
38

39
40
41

42
43
44

45
46
47

48
49

50
51

52
53
54

55
56
57

58
59
60

61
62
63

64
65

66
67

68
69


70
71
72
73

74
75
76

77
78
79


80
81
82

83
84
85

86
87


88
89
90

91
92

93
94
95

96
97
98

99
100
101

102
103
104

105
106
107

108
109
110


111
112
113

114
115
116

117
118
119

120
121

122
123
124

125
126
127


128
129
130
131
132
133
134
135
136













-
+





-
-
-
+
+
+

-
-
+
+











-
-
-
-
-
-
-
-
-


-
+


-
+


-
+


-
+

-
+

-
+


-
+


-
+


-
+


-
+

-
+

-
+

-
-
+
+


-
+


-
+


-
-
+
+

-
+


-
+

-
-
+
+

-
+

-
+


-
+


-
+


-
+


-
+


-
+


-
-
+
+

-
+


-
+


-
+

-
+


-
+


-
-
+
+







/*
 * tkScale.c --
 *
 *	This module implements a scale widgets for the Tk toolkit. A scale
 *	displays a slider that can be adjusted to change a value; it also
 *	displays numeric labels and a textual label, if desired.
 *
 *	The modifications to use floating-point values are based on an
 *	implementation by Paul Mackerras. The -variable option is due to
 *	Henning Schulzrinne. All of these are used with permission.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 * 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.
 */

#include "tkInt.h"
#include "tkScale.h"
#include "default.h"
#include "default.h"
#include "tkInt.h"
#include "tkScale.h"

#if defined(_WIN32)
#define snprintf _snprintf
#ifdef _WIN32
#include "tkWinInt.h"
#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[] = {
    "horizontal", "vertical", NULL
};

/*
 * The following table defines the legal values for the -state option. It is
 * used together with the "enum state" declaration in tkScale.h.
 */

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),
	DEF_SCALE_ACTIVE_BG_COLOR, -1, Tk_Offset(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),
	DEF_SCALE_BG_COLOR, -1, Tk_Offset(TkScale, bgBorder),
	0, DEF_SCALE_BG_MONO, 0},
    {TK_OPTION_DOUBLE, "-bigincrement", "bigIncrement", "BigIncrement",
	DEF_SCALE_BIG_INCREMENT, TCL_INDEX_NONE, offsetof(TkScale, bigIncrement),
	DEF_SCALE_BIG_INCREMENT, -1, Tk_Offset(TkScale, bigIncrement),
	0, 0, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_SCALE_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(TkScale, borderWidth),
	DEF_SCALE_BORDER_WIDTH, -1, Tk_Offset(TkScale, borderWidth),
	0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_SCALE_COMMAND, TCL_INDEX_NONE, offsetof(TkScale, command),
	DEF_SCALE_COMMAND, -1, Tk_Offset(TkScale, command),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_SCALE_CURSOR, TCL_INDEX_NONE, offsetof(TkScale, cursor),
	DEF_SCALE_CURSOR, -1, Tk_Offset(TkScale, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-digits", "digits", "Digits",
	DEF_SCALE_DIGITS, TCL_INDEX_NONE, offsetof(TkScale, digits),
	DEF_SCALE_DIGITS, -1, Tk_Offset(TkScale, digits),
	0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_SCALE_FONT, TCL_INDEX_NONE, offsetof(TkScale, tkfont), 0, 0, 0},
	DEF_SCALE_FONT, -1, Tk_Offset(TkScale, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_SCALE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkScale, textColorPtr), 0,
	DEF_SCALE_FG_COLOR, -1, Tk_Offset(TkScale, textColorPtr), 0,
	(ClientData) DEF_SCALE_FG_MONO, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From", DEF_SCALE_FROM, TCL_INDEX_NONE,
	offsetof(TkScale, fromValue), 0, 0, 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,
	TCL_INDEX_NONE, offsetof(TkScale, highlightBorder),
	-1, Tk_Offset(TkScale, highlightBorder),
	0, DEF_SCALE_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCALE_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkScale, highlightColorPtr),
	DEF_SCALE_HIGHLIGHT, -1, Tk_Offset(TkScale, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(TkScale, highlightWidth), 0, 0, 0},
	"HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(TkScale, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-label", "label", "Label",
	DEF_SCALE_LABEL, TCL_INDEX_NONE, offsetof(TkScale, label),
	DEF_SCALE_LABEL, -1, Tk_Offset(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},
	DEF_SCALE_LENGTH, -1, Tk_Offset(TkScale, length), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	DEF_SCALE_ORIENT, TCL_INDEX_NONE, offsetof(TkScale, orient),
	0, orientStrings, 0},
	DEF_SCALE_ORIENT, -1, Tk_Offset(TkScale, orient),
	TK_OPTION_ENUM_VAR, orientStrings, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_SCALE_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, relief), 0, 0, 0},
	DEF_SCALE_RELIEF, -1, Tk_Offset(TkScale, relief), 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCALE_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkScale, repeatDelay),
	DEF_SCALE_REPEAT_DELAY, -1, Tk_Offset(TkScale, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCALE_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkScale, repeatInterval),
	DEF_SCALE_REPEAT_INTERVAL, -1, Tk_Offset(TkScale, repeatInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-resolution", "resolution", "Resolution",
	DEF_SCALE_RESOLUTION, TCL_INDEX_NONE, offsetof(TkScale, resolution),
	DEF_SCALE_RESOLUTION, -1, Tk_Offset(TkScale, resolution),
	0, 0, 0},
    {TK_OPTION_BOOLEAN, "-showvalue", "showValue", "ShowValue",
	DEF_SCALE_SHOW_VALUE, TCL_INDEX_NONE, offsetof(TkScale, showValue),
	DEF_SCALE_SHOW_VALUE, -1, Tk_Offset(TkScale, showValue),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-sliderlength", "sliderLength", "SliderLength",
	DEF_SCALE_SLIDER_LENGTH, TCL_INDEX_NONE, offsetof(TkScale, sliderLength),
	DEF_SCALE_SLIDER_LENGTH, -1, Tk_Offset(TkScale, sliderLength),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-sliderrelief", "sliderRelief", "SliderRelief",
	DEF_SCALE_SLIDER_RELIEF, TCL_INDEX_NONE, offsetof(TkScale, sliderRelief),
	DEF_SCALE_SLIDER_RELIEF, -1, Tk_Offset(TkScale, sliderRelief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_SCALE_STATE, TCL_INDEX_NONE, offsetof(TkScale, state),
	0, stateStrings, 0},
	DEF_SCALE_STATE, -1, Tk_Offset(TkScale, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCALE_TAKE_FOCUS, offsetof(TkScale, takeFocusPtr), TCL_INDEX_NONE,
	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, TCL_INDEX_NONE, offsetof(TkScale, tickInterval),
	DEF_SCALE_TICK_INTERVAL, -1, Tk_Offset(TkScale, tickInterval),
	0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	DEF_SCALE_TO, TCL_INDEX_NONE, offsetof(TkScale, toValue), 0, 0, 0},
	DEF_SCALE_TO, -1, Tk_Offset(TkScale, toValue), 0, 0, 0},
    {TK_OPTION_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCALE_TROUGH_COLOR, TCL_INDEX_NONE, offsetof(TkScale, troughColorPtr),
	DEF_SCALE_TROUGH_COLOR, -1, Tk_Offset(TkScale, troughColorPtr),
	0, DEF_SCALE_TROUGH_MONO, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_SCALE_VARIABLE, offsetof(TkScale, varNamePtr), TCL_INDEX_NONE,
	DEF_SCALE_VARIABLE, Tk_Offset(TkScale, varNamePtr), -1,
	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}
	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.
 */
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162







-
+







 * 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 void		DestroyScale(char *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,
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249

250
251
252
253
254
255
256







-
+







-







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ScaleObjCmd(
    ClientData dummy,	/* NULL. */
    ClientData clientData,	/* 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),
340
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357







-
+












-
+







    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)
    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;
    }

    /*
     * The widget was just created, no command callback must be invoked.
     */

    scalePtr->flags &= ~INVOKE_COMMAND;

    Tcl_SetObjResult(interp, Tk_NewWindowObj(scalePtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(scalePtr->tkwin));
    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
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416







-
+




















-
+








-
+







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;
    TkScale *scalePtr = 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,
	objPtr = Tk_GetOptionValue(interp, (char *) 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,
	    objPtr = Tk_GetOptionInfo(interp, (char *) scalePtr,
		    scalePtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, scalePtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
448
449
450
451
452
453
454
455
456


457
458
459
460
461
462
463
438
439
440
441
442
443
444


445
446
447
448
449
450
451
452
453







-
-
+
+







		    + 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);
	coords[0] = Tcl_NewIntObj(x);
	coords[1] = Tcl_NewIntObj(y);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;
    }
    case COMMAND_GET: {
	double value;
	int x, y;

537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541







-
+







 *	Everything associated with the scale is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyScale(
    void *memPtr)	/* Info about scale widget. */
    char *memPtr)	/* Info about scale widget. */
{
    TkScale *scalePtr = (TkScale *) memPtr;

    scalePtr->flags |= SCALE_DELETED;

    Tcl_DeleteCommandFromToken(scalePtr->interp, scalePtr->widgetCmd);
    if (scalePtr->flags & REDRAW_PENDING) {
622
623
624
625
626
627
628
629

630
631
632
633
634
635
636
612
613
614
615
616
617
618

619
620
621
622
623
624
625
626







-
+








    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, scalePtr,
	    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.
677
678
679
680
681
682
683
684

685
686
687
688
689
690
691
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681







-
+







		^ ((scalePtr->toValue - scalePtr->fromValue) < 0)) {
	    scalePtr->tickInterval = -scalePtr->tickInterval;
	}

	ComputeFormat(scalePtr, 0);
	ComputeFormat(scalePtr, 1);

	scalePtr->labelLength = scalePtr->label ? strlen(scalePtr->label) : 0;
	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;
764
765
766
767
768
769
770
771

772
773
774
775
776
777
778
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768







-
+








static void
ScaleWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    TkScale *scalePtr = (TkScale *)instanceData;
    TkScale *scalePtr = 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;
980
981
982
983
984
985
986
987

988
989

990
991
992
993

994
995

996
997
998
999
1000
1001
1002
970
971
972
973
974
975
976

977
978

979
980
981
982

983
984

985
986
987
988
989
990
991
992







-
+

-
+



-
+

-
+







    }
    if (mostSigDigit < 0) {
	fDigits++;			/* Zero to left of decimal point. */
    }

    if (forTicks) {
	if (fDigits <= eDigits) {
	    sprintf(scalePtr->tickFormat, "%%.%df", afterDecimal);
	    snprintf(scalePtr->tickFormat, sizeof(scalePtr->tickFormat), "%%.%df", afterDecimal);
	} else {
	    sprintf(scalePtr->tickFormat, "%%.%de", numDigits - 1);
	    snprintf(scalePtr->tickFormat, sizeof(scalePtr->tickFormat), "%%.%de", numDigits - 1);
	}
    } else {
	if (fDigits <= eDigits) {
	    sprintf(scalePtr->valueFormat, "%%.%df", afterDecimal);
	    snprintf(scalePtr->valueFormat, sizeof(scalePtr->valueFormat), "%%.%df", afterDecimal);
	} else {
	    sprintf(scalePtr->valueFormat, "%%.%de", numDigits - 1);
	    snprintf(scalePtr->valueFormat, sizeof(scalePtr->valueFormat), "%%.%de", numDigits - 1);
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1162







-
+







 */

static void
ScaleEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    TkScale *scalePtr = 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);
1206
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1196
1197
1198
1199
1200
1201
1202

1203
1204
1205
1206
1207
1208
1209
1210







-
+







 *----------------------------------------------------------------------
 */

static void
ScaleCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    TkScale *scalePtr = 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.
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
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







+








-
+




-
-







 *	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. */
{
    TkScale *scalePtr = (TkScale *)clientData;
    TkScale *scalePtr = 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) {
Changes to generic/tkScale.h.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15






-
-
+
+







/*
 * tkScale.h --
 *
 *	Declarations of types and functions used to implement the scale
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright (c) 1999-2000 by Scriptics Corporation.
 * Copyright (c) 1996 Sun Microsystems, Inc.
 * Copyright (c) 1999-2000 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKSCALE
#define _TKSCALE
69
70
71
72
73
74
75
76

77
78

79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
69
70
71
72
73
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
    char valueFormat[16];	/* Snprintf conversion specifier computed from
				 * digits and other information. */
    char tickFormat[16];	/* Sprintf conversion specifier computed from
    char tickFormat[16];	/* Snprintf 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. */
    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:
     */
Changes to generic/tkScrollbar.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

61
62
63

64
65
66

67
68
69

70
71

72
73

74
75
76

77
78

79
80

81
82

83
84
85

86
87
88

89
90
91

92
93
94
95
96
97
98
29
30
31
32
33
34
35

36
37
38

39
40
41

42
43

44
45
46

47
48
49
50
51

52
53

54
55
56

57
58
59

60
61
62

63
64
65

66
67
68

69
70

71
72

73
74
75

76
77

78
79

80
81

82
83
84

85
86
87

88
89
90

91
92
93
94
95
96
97
98







-
+


-
+


-
+

-
+


-
+




-
+

-
+


-
+


-
+


-
+


-
+


-
+

-
+

-
+


-
+

-
+

-
+

-
+


-
+


-
+


-
+








/*
 * Information used for argv parsing.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCROLLBAR_ACTIVE_BG_COLOR, offsetof(TkScrollbar, activeBorder),
	DEF_SCROLLBAR_ACTIVE_BG_COLOR, Tk_Offset(TkScrollbar, activeBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_SCROLLBAR_ACTIVE_BG_MONO, offsetof(TkScrollbar, activeBorder),
	DEF_SCROLLBAR_ACTIVE_BG_MONO, Tk_Offset(TkScrollbar, activeBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
	DEF_SCROLLBAR_ACTIVE_RELIEF, offsetof(TkScrollbar, activeRelief), 0, NULL},
	DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(TkScrollbar, activeRelief), 0, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_SCROLLBAR_BG_COLOR, offsetof(TkScrollbar, bgBorder),
	DEF_SCROLLBAR_BG_COLOR, Tk_Offset(TkScrollbar, bgBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_SCROLLBAR_BG_MONO, offsetof(TkScrollbar, bgBorder),
	DEF_SCROLLBAR_BG_MONO, Tk_Offset(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},
	DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(TkScrollbar, borderWidth), 0, NULL},
    {TK_CONFIG_STRING, "-command", "command", "Command",
	DEF_SCROLLBAR_COMMAND, offsetof(TkScrollbar, command),
	DEF_SCROLLBAR_COMMAND, Tk_Offset(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},
	DEF_SCROLLBAR_CURSOR, Tk_Offset(TkScrollbar, cursor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-elementborderwidth", "elementBorderWidth",
	"BorderWidth", DEF_SCROLLBAR_EL_BORDER_WIDTH,
	offsetof(TkScrollbar, elementBorderWidth), 0, NULL},
	Tk_Offset(TkScrollbar, elementBorderWidth), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG,
	offsetof(TkScrollbar, highlightBgColorPtr), 0, NULL},
	Tk_Offset(TkScrollbar, highlightBgColorPtr), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_SCROLLBAR_HIGHLIGHT,
	offsetof(TkScrollbar, highlightColorPtr), 0, NULL},
	Tk_Offset(TkScrollbar, highlightColorPtr), 0, NULL},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_SCROLLBAR_HIGHLIGHT_WIDTH, offsetof(TkScrollbar, highlightWidth), 0, NULL},
	DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(TkScrollbar, highlightWidth), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
	DEF_SCROLLBAR_JUMP, offsetof(TkScrollbar, jump), 0, NULL},
	DEF_SCROLLBAR_JUMP, Tk_Offset(TkScrollbar, jump), 0, NULL},
    {TK_CONFIG_CUSTOM, "-orient", "orient", "Orient",
	DEF_SCROLLBAR_ORIENT, offsetof(TkScrollbar, vertical), 0,
	DEF_SCROLLBAR_ORIENT, Tk_Offset(TkScrollbar, vertical), 0,
	&orientOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_SCROLLBAR_RELIEF, offsetof(TkScrollbar, relief), 0, NULL},
	DEF_SCROLLBAR_RELIEF, Tk_Offset(TkScrollbar, relief), 0, NULL},
    {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SCROLLBAR_REPEAT_DELAY, offsetof(TkScrollbar, repeatDelay), 0, NULL},
	DEF_SCROLLBAR_REPEAT_DELAY, Tk_Offset(TkScrollbar, repeatDelay), 0, NULL},
    {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SCROLLBAR_REPEAT_INTERVAL, offsetof(TkScrollbar, repeatInterval), 0, NULL},
	DEF_SCROLLBAR_REPEAT_INTERVAL, Tk_Offset(TkScrollbar, repeatInterval), 0, NULL},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_SCROLLBAR_TAKE_FOCUS, offsetof(TkScrollbar, takeFocus),
	DEF_SCROLLBAR_TAKE_FOCUS, Tk_Offset(TkScrollbar, takeFocus),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCROLLBAR_TROUGH_COLOR, offsetof(TkScrollbar, troughColorPtr),
	DEF_SCROLLBAR_TROUGH_COLOR, Tk_Offset(TkScrollbar, troughColorPtr),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
	DEF_SCROLLBAR_TROUGH_MONO, offsetof(TkScrollbar, troughColorPtr),
	DEF_SCROLLBAR_TROUGH_MONO, Tk_Offset(TkScrollbar, troughColorPtr),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	tkDefScrollbarWidth, offsetof(TkScrollbar, width), 0, NULL},
	tkDefScrollbarWidth, Tk_Offset(TkScrollbar, width), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations for functions defined later in this file:
 */

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
175
176
177
178
179
180
181

182
183
184
185

186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204







-




-











-
+







    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));
    Tcl_SetObjResult(interp, TkNewWindowObj(scrollPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarWidgetObjCmd --
222
223
224
225
226
227
228
229
230


231
232
233
234
235
236
237
220
221
222
223
224
225
226


227
228
229
230
231
232
233
234
235







-
-
+
+







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;
    int result = TCL_OK;
    int length, cmdIndex;
    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
267
268
269
270
271
272
273
274

275
276
277
278
279
280

281
282
283
284
285
286
287
265
266
267
268
269
270
271

272
273
274
275
276
277

278
279
280
281
282
283
284
285







-
+





-
+







	    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];
	c = Tcl_GetStringFromObj(objv[2], &length)[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)) {
	} else if ((c == 's') && (strncmp(Tcl_GetString(objv[2]), "slider", length) == 0)) {
	    scrollPtr->activeField = SLIDER;
	} else {
	    scrollPtr->activeField = OUTSIDE;
	}
	if (oldActiveField != scrollPtr->activeField) {
	    TkScrollbarEventuallyRedraw(scrollPtr);
	}
375
376
377
378
379
380
381
382
383
384
385
386
387









388
389
390
391
392
393
394
395
396
397
398
399
400
401
373
374
375
376
377
378
379






380
381
382
383
384
385
386
387
388
389

390




391
392
393
394
395
396
397







-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-

-
-
-
-







    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);
	if (scrollPtr->flags & NEW_STYLE_COMMANDS) {
	    resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction);
	    resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs));
	} else {
	    resObjs[0] = Tcl_NewIntObj(scrollPtr->totalUnits);
	    resObjs[1] = Tcl_NewIntObj(scrollPtr->windowUnits);
	    resObjs[2] = Tcl_NewIntObj(scrollPtr->firstUnit);
	    resObjs[3] = Tcl_NewIntObj(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) {
413
414
415
416
417
418
419


420
421
422
423
424
425
426
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424







+
+







	case BOTTOM_GAP:	zone = "trough2"; break;
	case BOTTOM_ARROW:	zone = "arrow2";  break;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1));
	break;
    }
    case COMMAND_SET: {
	int totalUnits, windowUnits, firstUnit, lastUnit;

	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) {
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
434
435
436
437
438
439
440


441
442

443
444
445
446
447
448
449







-
-
+

-







	    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;
	    scrollPtr->flags |= NEW_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) {
476
477
478
479
480
481
482
483

484
485
486


487
488
489
490
491
492
493
472
473
474
475
476
477
478

479

480
481
482
483
484
485
486
487
488
489
490







-
+
-


+
+







	    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;
	    scrollPtr->flags &= ~NEW_STYLE_COMMANDS;
#endif /* !TK_NO_DEPRECATED */
	} else {
		Tcl_WrongNumArgs(interp, 1, objv, "set firstFraction lastFraction");
		Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]),
			" set totalUnits windowUnits firstUnit lastUnit\"", NULL);
	    goto error;
	}
	TkpComputeScrollbarGeometry(scrollPtr);
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    }
    }
Changes to generic/tkScrollbar.h.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkScrollbar.h --
 *
 *	Declarations of types and functions used to implement the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * 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.
 */

#ifndef _TKSCROLLBAR
#define _TKSCROLLBAR
89
90
91
92
93
94
95
96

97
98
99
100
101
102


103
104
105

106
107
108

109
110

111
112
113
114
115
116
117
118
119
120
121
89
90
91
92
93
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 OLD_STYLE_COMMANDS flag is 1.
     * the NEW_STYLE_COMMANDS flag is 0.
     */

#ifndef TK_NO_DEPRECATED
    int totalUnits;		/* Total dimension of application, in units.
				 * Valid only if the OLD_STYLE_COMMANDS flag
				 * is set. */
				 * 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 OLD_STYLE_COMMANDS flag is set. */
				 * if the NEW_STYLE_COMMANDS flag isn't set. */
    int firstUnit;		/* Number of last unit visible in
				 * application's window. Valid only if the
				 * OLD_STYLE_COMMANDS flag is set. */
				 * NEW_STYLE_COMMANDS flag isn't set. */
    int lastUnit;		/* Index of last unit visible in window.
				 * Valid only if the OLD_STYLE_COMMANDS flag
				 * Valid only if the NEW_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. */

144
145
146
147
148
149
150
151

152
153
154


155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
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 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
 * NEW_STYLE_COMMANDS:		Non-zero means the new style of commands
 *				should be used to communicate with the widget:
 *				".t yview 40", instead of
 *				".t yview scroll 2 lines", for example.
 *				".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
#ifndef TK_NO_DEPRECATED
#   define OLD_STYLE_COMMANDS	2
#define NEW_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.
 */

Changes to generic/tkSelect.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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







+
+
+
+












-
+







 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkSelect.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * When a selection handler is set up by invoking "selection handle", one of
 * the following data structures is set up to hold information about the
 * command to invoke and its interpreter.
 */

typedef struct {
    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
    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;

/*
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74







-
-
+
+







} 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 int		HandleTclCommand(ClientData clientData,
			    int offset, char *buffer, int maxBytes);
static void		LostSelection(ClientData clientData);
static int		SelGetProc(ClientData clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *--------------------------------------------------------------
 *
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204







-
+







		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 +
		    unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + 1 +
			    ((CommandInfo *)clientData)->cmdLength;

		    selPtr->clientData = ckalloc(cmdInfoLen);
		    memcpy(selPtr->clientData, clientData, cmdInfoLen);
		} else {
		    selPtr->clientData = clientData;
		}
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371







-
+







    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
    ClientData clearData = NULL;/* Initialization needed only to prevent
				 * compiler warning. */

    if (dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }
    Tk_MakeWindowExist(tkwin);

462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480







-
+







{
    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
    ClientData clearData = NULL;/* Initialization needed only to prevent
				 * compiler warning. */

    if (dispPtr->multipleAtom == None) {
	TkSelInit(tkwin);
    }

    for (infoPtr = dispPtr->selectionInfoPtr, prevPtr = NULL;
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
831
832
833
834
835
836
837

838
839
840
841
842
843
844
845







-
+







    }

    case SELECTION_HANDLE: {
	Atom target, format;
	const char *targetName = NULL;
	const char *formatName = NULL;
	CommandInfo *cmdInfoPtr;
	TkSizeT cmdLength;
	int cmdLength;
	static const char *const handleOptionStrings[] = {
	    "-format", "-selection", "-type", NULL
	};
	enum handleOptions {
	    HANDLE_FORMAT, HANDLE_SELECTION, HANDLE_TYPE
	};
	int handleIndex;
896
897
898
899
900
901
902
903

904
905
906
907

908
909
910
911
912
913
914
900
901
902
903
904
905
906

907
908
909
910

911
912
913
914
915
916
917
918







-
+



-
+







	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);
	string = Tcl_GetStringFromObj(objs[1], &cmdLength);
	if (cmdLength == 0) {
	    Tk_DeleteSelHandler(tkwin, selection, target);
	} else {
	    cmdInfoPtr = (CommandInfo *)ckalloc(offsetof(CommandInfo, command)
	    cmdInfoPtr = (CommandInfo *)ckalloc(Tk_Offset(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);
988
989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1006







-
+








	    /*
	     * Ignore the internal clipboard window.
	     */

	    if ((infoPtr != NULL)
		    && (infoPtr->owner != winPtr->dispPtr->clipWindow)) {
		Tcl_SetObjResult(interp, Tk_NewWindowObj(infoPtr->owner));
		Tcl_SetObjResult(interp, TkNewWindowObj(infoPtr->owner));
	    }
	    return TCL_OK;
	}

	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objs[0]), tkwin);
	if (tkwin == NULL) {
	    return TCL_ERROR;
1187
1188
1189
1190
1191
1192
1193
1194

1195
1196
1197
1198
1199
1200
1201
1191
1192
1193
1194
1195
1196
1197

1198
1199
1200
1201
1202
1203
1204
1205







-
+







    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
     *	  https://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
1242
1243
1244
1245
1246
1247
1248
1249

1250
1251
1252
1253
1254
1255
1256
1246
1247
1248
1249
1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
1260







-
+







	if (infoPtr->selection == eventPtr->xselectionclear.selection) {
	    break;
	}
	prevPtr = infoPtr;
    }

    if (infoPtr != NULL && (infoPtr->owner == tkwin) &&
	    (eventPtr->xselectionclear.serial >= (unsigned long) infoPtr->serial)) {
	    (eventPtr->xselectionclear.serial >= (unsigned) infoPtr->serial)) {
	if (prevPtr == NULL) {
	    dispPtr->selectionInfoPtr = infoPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = infoPtr->nextPtr;
	}

	/*
1313
1314
1315
1316
1317
1318
1319
1320

1321
1322
1323

1324
1325
1326

1327
1328
1329
1330
1331
1332
1333
1317
1318
1319
1320
1321
1322
1323

1324
1325
1326

1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
1337







-
+


-
+


-
+







 *
 * Side effects:
 *	None except for things done by the Tcl command.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
HandleTclCommand(
    ClientData clientData,	/* Information about command to execute. */
    TkSizeT offset,			/* Return selection bytes starting at this
    int offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TkSizeT maxBytes)		/* Maximum # of bytes to store at buffer. */
    int 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;
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
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







-
+




















-
+
















-
-
+
+








-
+



-
+




-
+







    Tcl_Preserve(interp);

    /*
     * Compute the proper byte offset in the case where the last chunk split a
     * character.
     */

    if ((int)offset == cmdInfoPtr->byteOffset) {
    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.
     */

    command = Tcl_ObjPrintf("%s %d %d",
	    cmdInfoPtr->command, charOffset, (int)maxBytes);
	    cmdInfoPtr->command, charOffset, 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);
	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 <= (int)maxBytes) {
	    if (length <= maxBytes) {
		cmdInfoPtr->charOffset += Tcl_NumUtfChars(string, -1);
		cmdInfoPtr->buffer[0] = '\0';
	    } else {
		int ch;
		Tcl_UniChar ch = 0;
		p = string;
		string += count;
		numChars = 0;
		while (p < string) {
		    p += TkUtfToUniChar(p, &ch);
		    p += Tcl_UtfToUniChar(p, &ch);
		    numChars++;
		}
		cmdInfoPtr->charOffset += numChars;
		length = p - string;
		if (length > 0) {
		    strncpy(cmdInfoPtr->buffer, string, length);
		}
1472
1473
1474
1475
1476
1477
1478
1479

1480
1481
1482
1483
1484
1485
1486
1476
1477
1478
1479
1480
1481
1482

1483
1484
1485
1486
1487
1488
1489
1490







-
+







    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);
	snprintf(buffer, maxBytes, "0x%x", (unsigned int) infoPtr->time);
	*typePtr = XA_INTEGER;
	return strlen(buffer);
    }

    if (target == dispPtr->targetsAtom) {
	TkSelHandler *selPtr;
	int length;
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
21
22
23
24
25
26
27


28
29
30
31



32
33
34

35
36
37
38
39
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. */
#if TCL_MAJOR_VERSION > 8
    unsigned long serial;	/* Serial number of last XSelectionSetOwner
    int 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. */
    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. */
    void *clientData;	/* Argument to pass to proc. */
    TkSizeT size;			/* Size of units returned by proc (8 for
    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;

/*
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
+







 * 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. */
    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. */
Changes to generic/tkSquare.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
62
63
64
65
66
67
68

69
70

71
72

73
74
75

76
77


78
79
80
81

82
83
84

85
86

87
88

89
90

91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107







-
+

-
+

-
+


-
+

-
-
+
+


-
+


-
+

-
+

-
+

-
+









-








/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	    "#d9d9d9", offsetof(Square, bgBorderPtr), TCL_INDEX_NONE, 0,
	    "#d9d9d9", Tk_Offset(Square, bgBorderPtr), -1, 0,
	    "white", 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1, 0,
	    "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0,
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, -1, 0,
	    "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	    "2", offsetof(Square, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    "2", Tk_Offset(Square, borderWidthPtr), -1, 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,
	    "1", Tk_Offset(Square, doubleBufferPtr), -1, 0 , NULL, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, 0, -1, 0,
	    "-foreground", 0},
    {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
	    "#b03060", offsetof(Square, fgBorderPtr), TCL_INDEX_NONE, 0,
	    "#b03060", Tk_Offset(Square, fgBorderPtr), -1, 0,
	    "black", 0},
    {TK_OPTION_PIXELS, "-posx", "posx", "PosX", "0",
	    offsetof(Square, xPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    Tk_Offset(Square, xPtr), -1, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-posy", "posy", "PosY", "0",
	    offsetof(Square, yPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    Tk_Offset(Square, yPtr), -1, 0, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	    "raised", offsetof(Square, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    "raised", Tk_Offset(Square, reliefPtr), -1, 0, NULL, 0},
    {TK_OPTION_PIXELS, "-size", "size", "Size", "20",
	    offsetof(Square, sizeObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
	    Tk_Offset(Square, sizeObjPtr), -1, 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[]);

121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134

135
136
137
138
139
140
141







-
+







-







 *	A new widget is created and configured.
 *
 *--------------------------------------------------------------
 */

int
SquareObjCmd(
    ClientData dummy,	/* NULL. */
    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;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190







-
+











-
+








-
+







    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));
    squarePtr = 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)
    if (Tk_InitOptions(interp, (char *) 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,
    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;
    }

220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271

272
273
274
275
276
277

278
279
280
281
282
283
284
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268

269
270
271
272
273
274

275
276
277
278
279
280
281
282







-
+









-
+
















-
+










-
+





-
+





-
+







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;
    Square *squarePtr = 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 ...?");
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg 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,
	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, squarePtr,
	    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, squarePtr,
	    resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr,
		    squarePtr->optionTable, objv[2], squarePtr->tkwin);
	    if (resultObjPtr == NULL) {
		result = TCL_ERROR;
	    }
	} else {
	    result = Tk_SetOptions(interp, squarePtr,
	    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, squarePtr);
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333
334
335
313
314
315
316
317
318
319

320
321
322
323
324
325

326
327
328
329
330
331
332







-
+





-







 *	for squarePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
SquareConfigure(
    Tcl_Interp *dummy,		/* Used for error reporting. */
    Tcl_Interp *interp,		/* 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,
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392







-
+







 */

static void
SquareObjEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Square *squarePtr = (Square *)clientData;
    Square *squarePtr = clientData;

    if (eventPtr->type == Expose) {
	if (!squarePtr->updatePending) {
	    Tcl_DoWhenIdle(SquareDisplay, squarePtr);
	    squarePtr->updatePending = 1;
	}
    } else if (eventPtr->type == ConfigureNotify) {
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419







-
+







	    squarePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(squarePtr->interp,
		    squarePtr->widgetCmd);
	}
	if (squarePtr->updatePending) {
	    Tcl_CancelIdleCall(SquareDisplay, squarePtr);
	}
	Tcl_EventuallyFree(squarePtr, (Tcl_FreeProc *) SquareDestroy);
	Tcl_EventuallyFree(squarePtr, TCL_DYNAMIC);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SquareDeletedProc --
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445







-
+







 *----------------------------------------------------------------------
 */

static void
SquareDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Square *squarePtr = (Square *)clientData;
    Square *squarePtr = 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
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482







-
+







 *--------------------------------------------------------------
 */

static void
SquareDisplay(
    ClientData clientData)	/* Information about window. */
{
    Square *squarePtr = (Square *)clientData;
    Square *squarePtr = clientData;
    Tk_Window tkwin = squarePtr->tkwin;
    Pixmap pm = None;
    Drawable d;
    int borderWidth, size, relief;
    Tk_3DBorder bgBorder, fgBorder;
    int doubleBuffer;

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
528
529
530
531
532
533
534



























535
536
537
538
539
540
541







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    if (doubleBuffer) {
	XCopyArea(Tk_Display(tkwin), pm, Tk_WindowId(tkwin), squarePtr->gc,
		0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
		0, 0);
	Tk_FreePixmap(Tk_Display(tkwin), pm);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * SquareDestroy --
 *
 *	This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to
 *	clean up the internal structure of a square at a safe time (when
 *	no-one is using it anymore).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the square is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
SquareDestroy(
    void *memPtr)		/* Info about square widget. */
{
    Square *squarePtr = (Square *)memPtr;

    ckfree(squarePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * KeepInWindow --
 *
 *	Adjust the position of the square if necessary to keep it in the
Changes to generic/tkStubInit.c.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * tkStubInit.c --
 *
 *	This file contains the initializers for the Tk stub vectors.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * 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 "tkInt.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42






43
44
45
46
47
48



























49
50

















51
52
53
54
55
56
57
58
59
60
61







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88



89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129



130



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145


146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172




173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226







+







+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











-
-
-
-
-
-
-




+
+
+
+
+
+



+
+
+
+
+
+
+
+






-
-
-






-












+
+
+
-
-
+
+


















-
-
-

-
-
-
+
+
+
+
+
+
+
+
+






-
-








-
+
















+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




+
+







#include "tkMacOSXPrivate.h"
#endif

/* TODO: These ought to come in some other way */
#include "tkPlatDecls.h"
#include "tkIntXlibDecls.h"

static const TkIntStubs tkIntStubs;
MODULE_SCOPE const TkStubs tkStubs;

/*
 * Remove macro that might interfere with the definition below.
 */

#undef Tk_MainEx
#undef XVisualIDFromVisual
#undef Tk_FreeXId
#undef Tk_FreeStyleFromObj
#undef Tk_GetStyleFromObj
#undef TkWinGetPlatformId
#undef TkPutImage
#undef XPutImage
#undef XSynchronize
#undef XUngrabServer
#undef XNoOp
#undef XGrabServer
#undef XFree
#undef XFlush
#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
#undef Tk_FreeStyleFromObj
#define TkUnusedStubEntry 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
static int
doNothing(void)
{
    /* dummy implementation, no need to do anything */
    return 0;
}
#   define TkpWillDrawWidget ((int (*)(Tk_Window))(void *)doNothing)
#   define TkpRedrawWidget ((void (*)(Tk_Window))(void *)doNothing)
#endif

#if defined(MAC_OSX_TK)
#   define Tk_MacOSXGetNSWindowForDrawable TkMacOSXDrawable
#   define Tk_MacOSXGetCGContextForDrawable GetCGContextForDrawable
static void *GetCGContextForDrawable(Drawable d) {
	return TkMacOSXGetCGContextForDrawable(d);
}
#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 XCreateWindow 0
#   define XOffsetRegion 0
#   define XUnionRegion 0
#   define TkWmCleanup (void (*)(TkDisplay *))(void *)TkpSync
#   define TkSendCleanup (void (*)(TkDisplay *))(void *)TkpSync
#   define TkWmCleanup (void (*)(TkDisplay *)) TkpSync
#   define TkSendCleanup (void (*)(TkDisplay *)) 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 *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)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);
    snprintf(buf, TCL_INTEGER_SPACE, "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. */
{
    return XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);
}
    (void)colors;
    (void)ncolors;

    return XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);

TkRegion TkCreateRegion()
{
    return (TkRegion) XCreateRegion();
}

int TkDestroyRegion(TkRegion r)
{
	return XDestroyRegion((Region)r);
}

int TkSetRegion(Display *d, GC g, TkRegion r)
{
	return XSetRegion(d, g, (Region)r);
}

int TkUnionRectWithRegion(XRectangle *a, TkRegion b, TkRegion c)
{
	return XUnionRectWithRegion(a, (Region) b, (Region) c);
}

int TkClipBox(TkRegion a, XRectangle *b)
{
	return XClipBox((Region) a, b);
}

int TkIntersectRegion(TkRegion a, TkRegion b, TkRegion c)
{
	return 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);
}

int TkSubtractRegion (TkRegion a, TkRegion b, TkRegion c)
{
    return 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 TkpGetMS 0
#	define TkpGetCapture 0
#	define TkPointerDeadWindow 0
#	define TkpSetCapture 0
#	define TkpSetCursor 0
#	define TkWinCancelMouseTimer 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
241
242
243
244
245
246
247
248
249
250
251
252

253

254




255
256
257
258
259





260







261
262
263



264




265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280







+




-
+
-

-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
-
-
-
-
-
-
-
+
+
+
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+







#	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

#   endif
#   elif !defined(MAC_OSX_TK) /* UNIX */
#endif /* !_WIN32 */

#if defined(MAC_OSX_TCL)

int
TkPutImage(
#	undef TkClipBox
#	undef TkCreateRegion
#	undef TkDestroyRegion
#	undef TkIntersectRegion
#	undef TkRectInRegion
    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. */
#	undef TkSetRegion
    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. */
{
#	undef TkUnionRectWithRegion
#	undef TkSubtractRegion

	(void)colors;
	(void)ncolors;

#	define TkClipBox (int (*) (TkRegion, XRectangle *)) XClipBox
    return XPutImage(display, d, gc, image, src_x, src_y, dest_x, dest_y, width, height);
}
#endif /* MAC_OSX_TCL */

#	define TkCreateRegion (TkRegion (*) ()) XCreateRegion
#	define TkDestroyRegion (int (*) (TkRegion)) XDestroyRegion
#	define TkIntersectRegion (int (*) (TkRegion, TkRegion, TkRegion)) XIntersectRegion
#	define TkRectInRegion (int (*) (TkRegion, int, int, unsigned int, unsigned int)) XRectInRegion
#	define TkSetRegion (int (*) (Display *, GC, TkRegion)) XSetRegion
#	define TkUnionRectWithRegion (int (*) (XRectangle *, TkRegion, TkRegion)) XUnionRectWithRegion
#	define TkSubtractRegion (int (*) (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.
 */

398
399
400
401
402
403
404
405
406
407
408
409
410
411







412
413
414
415
416
417
418
419

420

421
422
423
424
425
426
427
428
429

430

431
432
433
434
435
436
437
438
439
440

441

442
443
444
445
446
447
448
400
401
402
403
404
405
406







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456







-
-
-
-
-
-
-
+
+
+
+
+
+
+








+

+









+

+










+

+







    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 */
    TkClipBox, /* 113 */
    TkCreateRegion, /* 114 */
    TkDestroyRegion, /* 115 */
    TkIntersectRegion, /* 116 */
    TkRectInRegion, /* 117 */
    TkSetRegion, /* 118 */
    TkUnionRectWithRegion, /* 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 */
# if TCL_MAJOR_VERSION < 9
    0, /* 121 */ /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    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 */
# if TCL_MAJOR_VERSION < 9
    0, /* 122 */ /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    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 */
# if TCL_MAJOR_VERSION < 9
    0, /* 124 */ /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    TkpGetNativeAppBitmap, /* 124 */
#endif /* AQUA */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    0, /* 129 */
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479







-
+







    TkpGetKeySym, /* 138 */
    TkpInitKeymapInfo, /* 139 */
    TkPhotoGetValidRegion, /* 140 */
    TkWmStackorderToplevel, /* 141 */
    TkFocusFree, /* 142 */
    TkClipCleanup, /* 143 */
    TkGCCleanup, /* 144 */
    XSubtractRegion, /* 145 */
    TkSubtractRegion, /* 145 */
    TkStylePkgInit, /* 146 */
    TkStylePkgFree, /* 147 */
    TkToplevelWindowForCommand, /* 148 */
    TkGetOptionSpec, /* 149 */
    TkMakeRawCurve, /* 150 */
    TkMakeRawCurvePostscript, /* 151 */
    TkpDrawFrame, /* 152 */
515
516
517
518
519
520
521
522

523
524
525
526
527
528
529
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537







-
+







#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    0, /* 186 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    TkpWillDrawWidget, /* 186 */
#endif /* MACOSX */
    TkDebugPhotoStringMatchDef, /* 187 */
    TkUnusedStubEntry, /* 187 */
};

static const TkIntPlatStubs tkIntPlatStubs = {
    TCL_STUB_MAGIC,
    0,
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    TkAlignImageData, /* 0 */
583
584
585
586
587
588
589
590

591
592
593
594
595
596
597
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605







-
+







    TkpSetCapture, /* 4 */
    TkpSetCursor, /* 5 */
    TkpWmSetState, /* 6 */
    TkAboutDlg, /* 7 */
    TkMacOSXButtonKeyState, /* 8 */
    TkMacOSXClearMenubarActive, /* 9 */
    TkMacOSXDispatchMenuEvent, /* 10 */
    0, /* 11 */
    TkMacOSXInstallCursor, /* 11 */
    TkMacOSXHandleTearoffMenu, /* 12 */
    0, /* 13 */
    TkMacOSXDoHLEvent, /* 14 */
    0, /* 15 */
    TkMacOSXGetXWindow, /* 16 */
    TkMacOSXGrowToplevel, /* 17 */
    TkMacOSXHandleMenuSelect, /* 18 */
619
620
621
622
623
624
625
626

627
628

629
630
631
632
633
634
635
627
628
629
630
631
632
633

634
635

636
637
638
639
640
641
642
643







-
+

-
+







    0, /* 40 */
    TkMacOSXZoomToplevel, /* 41 */
    Tk_TopCoordsToWindow, /* 42 */
    TkMacOSXContainerId, /* 43 */
    TkMacOSXGetHostToplevel, /* 44 */
    TkMacOSXPreprocessMenu, /* 45 */
    TkpIsWindowFloating, /* 46 */
    TkpGetCapture, /* 47 */
    TkMacOSXGetCapture, /* 47 */
    0, /* 48 */
    TkMacOSXGetContainer, /* 49 */
    TkGetTransientMaster, /* 49 */
    TkGenerateButtonEvent, /* 50 */
    TkGenWMDestroyEvent, /* 51 */
    TkMacOSXSetDrawingEnabled, /* 52 */
    TkpGetMS, /* 53 */
    TkMacOSXDrawable, /* 54 */
    TkpScanWindowId, /* 55 */
#endif /* AQUA */
764
765
766
767
768
769
770
771

772
773
774
775
776
777
778
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786







-
+







    XUngrabPointer, /* 74 */
    XUnmapWindow, /* 75 */
    XWindowEvent, /* 76 */
    XDestroyIC, /* 77 */
    XFilterEvent, /* 78 */
    XmbLookupString, /* 79 */
    TkPutImage, /* 80 */
    0, /* 81 */
    XSetClipRectangles, /* 81 */
    XParseColor, /* 82 */
    XCreateGC, /* 83 */
    XFreeGC, /* 84 */
    XInternAtom, /* 85 */
    XSetBackground, /* 86 */
    XSetForeground, /* 87 */
    XSetClipMask, /* 88 */
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
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







-
-
-
-
-
-
+
+
+
+
+
+



-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

-
+







    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, /* 138 */
    0, /* 139 */
    0, /* 140 */
    0, /* 141 */
    0, /* 142 */
    0, /* 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 */
    0, /* 147 */
    0, /* 148 */
    0, /* 149 */
    0, /* 150 */
    0, /* 151 */
    0, /* 152 */
    0, /* 153 */
    0, /* 154 */
    0, /* 155 */
    0, /* 156 */
    0, /* 157 */
    TkUnusedStubEntry, /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+







-
+







-
-
+
+







-
-
-
+
+
+



-
+

-
-
-
-
-
-
+
+
+
+
+
+



-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
+
+














-
-
-
-
+
+
+
+

-
+

-
+








-
+







    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 */
    0, /* 92 */
    0, /* 93 */
    0, /* 94 */
    0, /* 95 */
    0, /* 96 */
    0, /* 97 */
    0, /* 98 */
    0, /* 99 */
    0, /* 100 */
    0, /* 101 */
    0, /* 102 */
    0, /* 103 */
    0, /* 104 */
    0, /* 105 */
    XSetClipRectangles, /* 106 */
    XFlush, /* 107 */
    XGrabServer, /* 108 */
    XUngrabServer, /* 109 */
    XFree, /* 110 */
    XNoOp, /* 111 */
    XSynchronize, /* 112 */
    XLookupColor, /* 113 */
    0, /* 113 */
    XVisualIDFromVisual, /* 114 */
    0, /* 115 */
    0, /* 116 */
    0, /* 117 */
    0, /* 118 */
    0, /* 119 */
    XOffsetRegion, /* 120 */
    XUnionRegion, /* 121 */
    XCreateWindow, /* 122 */
    0, /* 121 */
    0, /* 122 */
    0, /* 123 */
    0, /* 124 */
    0, /* 125 */
    0, /* 126 */
    0, /* 127 */
    0, /* 128 */
    XLowerWindow, /* 129 */
    XFillArcs, /* 130 */
    XDrawArcs, /* 131 */
    XDrawRectangles, /* 132 */
    0, /* 130 */
    0, /* 131 */
    0, /* 132 */
    0, /* 133 */
    0, /* 134 */
    0, /* 135 */
    XReparentWindow, /* 136 */
    0, /* 136 */
    XPutImage, /* 137 */
    XPolygonRegion, /* 138 */
    XPointInRegion, /* 139 */
    XVaCreateNestedList, /* 140 */
    XSetICValues, /* 141 */
    XGetICValues, /* 142 */
    XSetICFocus, /* 143 */
    0, /* 138 */
    0, /* 139 */
    0, /* 140 */
    0, /* 141 */
    0, /* 142 */
    0, /* 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 */
    0, /* 147 */
    0, /* 148 */
    0, /* 149 */
    0, /* 150 */
    0, /* 151 */
    0, /* 152 */
    0, /* 153 */
    0, /* 154 */
    0, /* 155 */
    0, /* 156 */
    XkbKeycodeToKeysym, /* 157 */
    XkbOpenDisplay, /* 158 */
#endif /* MACOSX */
    TkUnusedStubEntry, /* 158 */
#endif /* AQUA */
};

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 */
    Tk_MacOSXSetEmbedHandler, /* 0 */
    Tk_MacOSXTurnOffMenus, /* 1 */
    Tk_MacOSXTkOwnsCursor, /* 2 */
    TkMacOSXInitMenus, /* 3 */
    TkMacOSXInitAppleEvents, /* 4 */
    TkGenWMConfigureEvent_, /* 5 */
    TkGenWMConfigureEvent, /* 5 */
    TkMacOSXInvalClipRgns, /* 6 */
    0, /* 7 */
    TkMacOSXGetDrawablePort, /* 7 */
    TkMacOSXGetRootControl, /* 8 */
    Tk_MacOSXSetupTkNotifier, /* 9 */
    Tk_MacOSXIsAppInFront, /* 10 */
    Tk_MacOSXGetTkWindow, /* 11 */
    Tk_MacOSXGetCGContextForDrawable, /* 12 */
    Tk_MacOSXGetNSWindowForDrawable, /* 13 */
    0, /* 14 */
    0, /* 15 */
    TkGenWMConfigureEvent, /* 16 */
    TkGenWMConfigureEvent_, /* 16 */
#endif /* AQUA */
};

static const TkStubHooks tkStubHooks = {
    &tkPlatStubs,
    &tkIntStubs,
    &tkIntPlatStubs,
1146
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
1154
1155
1156
1157
1158
1159
1160

1161
1162
1163
1164
1165
1166
1167
1168







-
+







    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_GetImageMasterData, /* 98 */
    Tk_GetItemTypes, /* 99 */
    Tk_GetJoinStyle, /* 100 */
    Tk_GetJustify, /* 101 */
    Tk_GetNumMainWindows, /* 102 */
    Tk_GetOption, /* 103 */
    Tk_GetPixels, /* 104 */
    Tk_GetPixmap, /* 105 */
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

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







-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
-
-
+
+
-
-
+
-

+
    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 */
    0, /* 274 */
    0, /* 275 */
    0, /* 276 */
    0, /* 277 */
    0, /* 278 */
    0, /* 279 */
};

/* !END!: Do not edit above this line. */


#ifdef __CYGWIN__
void *Tk_GetHINSTANCE(void)
    0, /* 280 */
    0, /* 281 */
    0, /* 282 */
    0, /* 283 */
    0, /* 284 */
    0, /* 285 */
    0, /* 286 */
{
    void *hInstance = NULL;

    0, /* 287 */
    0, /* 288 */
    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
	    (const char *) &tkIntStubs, &hInstance);
    0, /* 289 */
    TkUnusedStubEntry, /* 290 */
    return hInstance;
}
};
#endif

/* !END!: Do not edit above this line. */
Changes to generic/tkStubLib.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkStubLib.c --
 *
 *	Stub object that will be statically linked into extensions that want
 *	to access Tk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 * Copyright (c) 1998 Paul Duffin.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+







Tk_InitStubs(
    Tcl_Interp *interp,
    const char *version,
    int exact)
{
    const char *packageName = "Tk";
    const char *errMsg = NULL;
    void *clientData = NULL;
    ClientData clientData = NULL;
    const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
	    packageName, version, 0, &clientData);
    const TkStubs *stubsPtr = (const TkStubs *)clientData;

    if (actualVersion == NULL) {
	return NULL;
    }
Changes to generic/tkStyle.c.
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165







-
+







 */

static const Tcl_ObjType styleObjType = {
    "style",			/* name */
    FreeStyleObjProc,		/* freeIntRepProc */
    DupStyleObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
    SetStyleFromAny		/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * TkStylePkgInit --
 *
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
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. */
    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,
	    (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin, width, height, inner,
	    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
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. */
    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,
	    (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin, x, y, width, height,
	    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
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. */
    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, (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin);
	    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
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. */
    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,
	    (char *)recordPtr, widgetSpecPtr->optionsPtr, tkwin, d, x, y, width,
	    recordPtr, widgetSpecPtr->optionsPtr, tkwin, d, x, y, width,
	    height, state);
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_CreateStyle --
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
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







-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-
-
+
+














-











-
-
-
-

-
+







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;
	}
	SetStyleFromAny(interp, objPtr);
    }
    return (Tk_Style)objPtr->internalRep.twoPtrValue.ptr1;
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *
 *---------------------------------------------------------------------------
 */
#undef Tk_FreeStyleFromObj
void
Tk_FreeStyleFromObj(
    TCL_UNUSED(Tcl_Obj *))
{
}

/*
 *----------------------------------------------------------------------
 *
 * 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.
 *	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;
    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;
    objPtr->internalRep.twoPtrValue.ptr1 = Tk_GetStyle(interp, name);

    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
Changes to generic/tkTest.c.
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18










-
+







/*
 * tkTest.c --
 *
 *	This file contains C command functions for a bunch of additional Tcl
 *	commands that are used for testing out Tcl's C interfaces. These
 *	commands are not normally included in Tcl applications; they're only
 *	used for testing.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * 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 STATIC_BUILD
#ifndef USE_TCL_STUBS
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
44
45
46
47
48
49
50



51




52
53
54
55
56
57
58







-
-
-

-
-
-
-







 * 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. */
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90







-
+







} TImageInstance;

/*
 * The type record for test images:
 */

static int		ImageCreate(Tcl_Interp *interp,
			    const char *name, int argc, Tcl_Obj *const objv[],
			    const char *name, int objc, 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,
184
185
186
187
188
189
190
191
192
193
194













195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
177
178
179
180
181
182
183




184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199



200
201
202
203
204
205
206
207
208
209
210



211
212
213
214
215
216
217







-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
-











-
-
-







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		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		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.
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242







-
+








int
Tktest_Init(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    static int initialized = 0;

    if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
    if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
	return TCL_ERROR;
    }
    if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
	return TCL_ERROR;
    }

    /*
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
264
265
266
267
268
269
270

271
272



273
274
275
276
277
278
279







-


-
-
-







	    (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);
335
336
337
338
339
340
341

342
343
344
345
346
347
348
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341







+







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;
368
369
370
371
372
373
374

375
376
377
378
379
380
381
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375







+







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;
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
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







-
+








-
+









-
+

-
+















-
+






+
















+
+
+



-
+

-
+

-
+

-
+



-
-
+
+
+
+
+
+

-
+


-
+


-
+


-
+

-
-
+
+


-
+


-
-
-
-
-
+
+
+
+
+

-
+


-
+


-
+






-
+







	"custom option",
	CustomOptionSet,
	CustomOptionGet,
	CustomOptionRestore,
	CustomOptionFree,
	INT2PTR(1)
    };
    Tk_Window mainWin = (Tk_Window)clientData;
    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 {
    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",
		offsetof(ExtensionWidgetRecord, base1ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(ExtensionWidgetRecord, base1ObjPtr), -1, 0, NULL, 0},
	{TK_OPTION_STRING, "-two", "two", "Two", "two",
		offsetof(ExtensionWidgetRecord, base2ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1, 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 {
	typedef struct TypesRecord {
	    TrivialCommandHeader header;
	    Tcl_Obj *booleanPtr;
	    Tcl_Obj *integerPtr;
	    Tcl_Obj *doublePtr;
	    Tcl_Obj *stringPtr;
	    Tcl_Obj *stringTablePtr;
	    Tcl_Obj *stringTablePtr2;
	    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 char *const stringTable2[] = {
	    "one", "two", NULL
	};
	static const Tk_OptionSpec typesSpecs[] = {
	    {TK_OPTION_BOOLEAN, "-boolean", "boolean", "Boolean", "1",
		offsetof(TypesRecord, booleanPtr), TCL_INDEX_NONE, 0, 0, 0x1},
		Tk_Offset(TypesRecord, booleanPtr), -1, 0, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "7",
		offsetof(TypesRecord, integerPtr), TCL_INDEX_NONE, 0, 0, 0x2},
		Tk_Offset(TypesRecord, integerPtr), -1, 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		offsetof(TypesRecord, doublePtr), TCL_INDEX_NONE, 0, 0, 0x4},
		Tk_Offset(TypesRecord, doublePtr), -1, 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String",
		"foo", offsetof(TypesRecord, stringPtr), TCL_INDEX_NONE,
		"foo", Tk_Offset(TypesRecord, stringPtr), -1,
		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},
		"one", Tk_Offset(TypesRecord, stringTablePtr), -1,
		0, stringTable, 0x10},
	    {TK_OPTION_STRING_TABLE,
		"-stringtable2", "StringTable2", "stringTable2",
		"two", Tk_Offset(TypesRecord, stringTablePtr2), -1,
		0, stringTable2, 0x10},
	    {TK_OPTION_COLOR, "-color", "color", "Color",
		"red", offsetof(TypesRecord, colorPtr), TCL_INDEX_NONE,
		"red", Tk_Offset(TypesRecord, colorPtr), -1,
		TK_CONFIG_NULL_OK, "black", 0x20},
	    {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12",
		offsetof(TypesRecord, fontPtr), TCL_INDEX_NONE,
		Tk_Offset(TypesRecord, fontPtr), -1,
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		offsetof(TypesRecord, bitmapPtr), TCL_INDEX_NONE,
		Tk_Offset(TypesRecord, bitmapPtr), -1,
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border",
		"blue", offsetof(TypesRecord, borderPtr), TCL_INDEX_NONE,
		"blue", Tk_Offset(TypesRecord, borderPtr), -1,
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised",
		offsetof(TypesRecord, reliefPtr), TCL_INDEX_NONE,
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
		Tk_Offset(TypesRecord, reliefPtr), -1,
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		offsetof(TypesRecord, cursorPtr), TCL_INDEX_NONE,
		Tk_Offset(TypesRecord, cursorPtr), -1,
		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_Offset(TypesRecord, justifyPtr), -1,
		0, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", "center",
		Tk_Offset(TypesRecord, anchorPtr), -1,
		0, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel",
		"1", offsetof(TypesRecord, pixelPtr), TCL_INDEX_NONE,
		"1", Tk_Offset(TypesRecord, pixelPtr), -1,
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL,
		"", offsetof(TypesRecord, customPtr), TCL_INDEX_NONE,
		"", Tk_Offset(TypesRecord, customPtr), -1,
		TK_CONFIG_NULL_OK, &CustomOption, 0x4000},
	    {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
		NULL, 0, TCL_INDEX_NONE, 0, "-color", 0x8000},
		NULL, 0, -1, 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,
	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));
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
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







+

-
+







-
+


















-
+














-
+

-
+


-
+


















-
+

-
+

-
+


-
-
+
+




-
+















-
+

-
+

















-
+





-
+







-
+







	recordPtr->reliefPtr = NULL;
	recordPtr->cursorPtr = NULL;
	recordPtr->justifyPtr = NULL;
	recordPtr->anchorPtr = NULL;
	recordPtr->pixelPtr = NULL;
	recordPtr->mmPtr = NULL;
	recordPtr->stringTablePtr = NULL;
	recordPtr->stringTablePtr2 = NULL;
	recordPtr->customPtr = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable,
	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, recordPtr, optionTable,
	    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(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,
	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);
	result = Tk_InitOptions(interp, (char *)recordPtr, optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
	    result = Tk_SetOptions(interp, (char *) recordPtr, optionTable,
		    objc-3, objv+3, tkwin, NULL, NULL);
	    if (result != TCL_OK) {
		Tk_FreeConfigOptions(recordPtr, optionTable, tkwin);
		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:
    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_Offset(ExtensionWidgetRecord, extension3ObjPtr), -1, 0, NULL, 0},
	    {TK_OPTION_STRING, "-four", "four", "Four", "four",
		offsetof(ExtensionWidgetRecord, extension4ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(ExtensionWidgetRecord, extension4ObjPtr), -1, 0, NULL, 0},
	    {TK_OPTION_STRING, "-two", "two", "Two", "two and a half",
		offsetof(ExtensionWidgetRecord, base2ObjPtr), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(ExtensionWidgetRecord, base2ObjPtr), -1, 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,
		Tk_Offset(ExtensionWidgetRecord, extension5ObjPtr), -1, 0, NULL, 0},
	    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0,
		(ClientData) baseSpecs, 0}
	};
	Tk_OptionTable optionTable;

	tkwin = Tk_CreateWindowFromPath(interp, (Tk_Window)clientData,
	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);
	result = Tk_InitOptions(interp, (char *)recordPtr, optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr, optionTable,
	    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 {
	typedef struct ErrorWidgetRecord {
	    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_Offset(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,
	return Tk_InitOptions(interp, (char *) &widgetRecord, optionTable,
		(Tk_Window) NULL);
    }

    case DEL:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tableName");
	    return TCL_ERROR;
834
835
836
837
838
839
840
841

842
843
844
845
846
847
848
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851







-
+







    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 {
	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
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







-
+

-
+

-
+

-
+



-
+


-
+


-
+


-
+


-
+

-
-
+
+


-
+


-
-
-
-
-
+
+
+
+
+

-
+


-
+


-
+


-
+






-
+






-
+















-
+




-
+







-
+















-
+










-
+

-
+

-
+

-
+

-
+








-
+








-
+


-
+







-
+










-
+





-
+











-
-
+
+










-
+






-
+



-
+














-
+


-
+










-
+







	} 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},
		-1, Tk_Offset(InternalRecord, boolean), 0, 0, 0x1},
	    {TK_OPTION_INT, "-integer", "integer", "Integer", "148962237",
		TCL_INDEX_NONE, offsetof(InternalRecord, integer), 0, 0, 0x2},
		-1, Tk_Offset(InternalRecord, integer), 0, 0, 0x2},
	    {TK_OPTION_DOUBLE, "-double", "double", "Double", "3.14159",
		TCL_INDEX_NONE, offsetof(InternalRecord, doubleValue), 0, 0, 0x4},
		-1, Tk_Offset(InternalRecord, doubleValue), 0, 0, 0x4},
	    {TK_OPTION_STRING, "-string", "string", "String", "foo",
		TCL_INDEX_NONE, offsetof(InternalRecord, string),
		-1, Tk_Offset(InternalRecord, string),
		TK_CONFIG_NULL_OK, 0, 0x8},
	    {TK_OPTION_STRING_TABLE,
		"-stringtable", "StringTable", "stringTable", "one",
		TCL_INDEX_NONE, offsetof(InternalRecord, index),
		-1, Tk_Offset(InternalRecord, index),
		TK_CONFIG_NULL_OK, internalStringTable, 0x10},
	    {TK_OPTION_COLOR, "-color", "color", "Color", "red",
		TCL_INDEX_NONE, offsetof(InternalRecord, colorPtr),
		-1, Tk_Offset(InternalRecord, colorPtr),
		TK_CONFIG_NULL_OK, "black", 0x20},
	    {TK_OPTION_FONT, "-font", "font", "Font", "Helvetica 12",
		TCL_INDEX_NONE, offsetof(InternalRecord, tkfont),
		-1, Tk_Offset(InternalRecord, tkfont),
		TK_CONFIG_NULL_OK, 0, 0x40},
	    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap", "gray50",
		TCL_INDEX_NONE, offsetof(InternalRecord, bitmap),
		-1, Tk_Offset(InternalRecord, bitmap),
		TK_CONFIG_NULL_OK, 0, 0x80},
	    {TK_OPTION_BORDER, "-border", "border", "Border", "blue",
		TCL_INDEX_NONE, offsetof(InternalRecord, border),
		-1, Tk_Offset(InternalRecord, border),
		TK_CONFIG_NULL_OK, "white", 0x100},
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", "raised",
		TCL_INDEX_NONE, offsetof(InternalRecord, relief),
	    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
		-1, Tk_Offset(InternalRecord, relief),
		TK_CONFIG_NULL_OK, 0, 0x200},
	    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", "xterm",
		TCL_INDEX_NONE, offsetof(InternalRecord, cursor),
		-1, Tk_Offset(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},
		-1, Tk_Offset(InternalRecord, justify),
		0, 0, 0x800},
	    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", "center",
		-1, Tk_Offset(InternalRecord, anchor),
		0, 0, 0x1000},
	    {TK_OPTION_PIXELS, "-pixel", "pixel", "Pixel", "1",
		TCL_INDEX_NONE, offsetof(InternalRecord, pixels),
		-1, Tk_Offset(InternalRecord, pixels),
		TK_CONFIG_NULL_OK, 0, 0x2000},
	    {TK_OPTION_WINDOW, "-window", "window", "Window", NULL,
		TCL_INDEX_NONE, offsetof(InternalRecord, tkwin),
		-1, Tk_Offset(InternalRecord, tkwin),
		TK_CONFIG_NULL_OK, 0, 0},
	    {TK_OPTION_CUSTOM, "-custom", NULL, NULL, "",
		TCL_INDEX_NONE, offsetof(InternalRecord, custom),
		-1, Tk_Offset(InternalRecord, custom),
		TK_CONFIG_NULL_OK, &CustomOption, 0x4000},
	    {TK_OPTION_SYNONYM, "-synonym", NULL, NULL,
		NULL, TCL_INDEX_NONE, TCL_INDEX_NONE, 0, "-color", 0x8000},
		NULL, -1, -1, 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,
	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 = 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->anchor = TK_ANCHOR_CENTER;
	recordPtr->pixels = 0;
	recordPtr->mm = 0.0;
	recordPtr->tkwin = NULL;
	recordPtr->custom = NULL;
	result = Tk_InitOptions(interp, recordPtr, optionTable,
	result = Tk_InitOptions(interp, (char *) 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,
	    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(recordPtr);
	}
	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, objv[2]);
	}
	break;
    }

    case NEW: {
	typedef struct {
	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",
		offsetof(FiveRecord, one), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(FiveRecord, one), -1, 0, NULL, 0},
	    {TK_OPTION_INT, "-two", "two", "Two", "2",
		offsetof(FiveRecord, two), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(FiveRecord, two), -1, 0, NULL, 0},
	    {TK_OPTION_INT, "-three", "three", "Three", "3",
		offsetof(FiveRecord, three), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(FiveRecord, three), -1, 0, NULL, 0},
	    {TK_OPTION_INT, "-four", "four", "Four", "4",
		offsetof(FiveRecord, four), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(FiveRecord, four), -1, 0, NULL, 0},
	    {TK_OPTION_STRING, "-five", NULL, NULL, NULL,
		offsetof(FiveRecord, five), TCL_INDEX_NONE, 0, NULL, 0},
		Tk_Offset(FiveRecord, five), -1, 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 = 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,
	result = Tk_InitOptions(interp, (char *) recordPtr,
		recordPtr->header.optionTable, (Tk_Window) NULL);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr,
	    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(recordPtr,
		Tk_FreeConfigOptions((char *) recordPtr,
			recordPtr->header.optionTable, (Tk_Window) NULL);
	    }
	}
	if (result != TCL_OK) {
	    ckfree(recordPtr);
	}

	break;
    }
    case NOT_ENOUGH_PARAMS: {
	typedef struct {
	typedef struct NotEnoughRecord {
	    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_Offset(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,
	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 {
	typedef struct ContentRecord {
	    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_Offset(ContentRecord, windowPtr), -1, 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);
		(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,
	result = Tk_InitOptions(interp,  (char *) recordPtr,
		recordPtr->header.optionTable, tkwin);
	if (result == TCL_OK) {
	    result = Tk_SetOptions(interp, recordPtr,
	    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,
			recordPtr, TrivialCmdDeletedProc);
		Tk_CreateEventHandler(tkwin, StructureNotifyMask,
			TrivialEventProc, recordPtr);
		Tcl_SetObjResult(interp, objv[2]);
	    } else {
		Tk_FreeConfigOptions(recordPtr,
		Tk_FreeConfigOptions((char *) recordPtr,
			recordPtr->header.optionTable, tkwin);
	    }
	}
	if (result != TCL_OK) {
	    Tk_DestroyWindow(tkwin);
	    ckfree(recordPtr);
	}
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
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







-
+




-
+

















-
+










-
+







-
+







-
+



-
+




-
+




-
+







	"cget", "configure", "csave", NULL
    };
    enum {
	CGET, CONFIGURE, CSAVE
    };
    Tcl_Obj *resultObjPtr;
    int index, mask;
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *)clientData;
    TrivialCommandHeader *headerPtr = (TrivialCommandHeader *) clientData;
    Tk_Window tkwin = headerPtr->tkwin;
    Tk_SavedOptions saved;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg 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,
	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, clientData,
	    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, clientData,
	    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, clientData,
	    result = Tk_SetOptions(interp, (char *) clientData,
		    headerPtr->optionTable, objc - 2, objv + 2,
		    tkwin, NULL, &mask);
	    if (result == TCL_OK) {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(mask));
		Tcl_SetObjResult(interp, Tcl_NewIntObj(mask));
	    }
	}
	break;
    case CSAVE:
	result = Tk_SetOptions(interp, clientData,
	result = Tk_SetOptions(interp, (char *) clientData,
		headerPtr->optionTable, objc - 2, objv + 2,
		tkwin, &saved, &mask);
	Tk_FreeSavedOptions(&saved);
	if (result == TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(mask));
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(mask));
	}
	break;
    }
  done:
    Tcl_Release(clientData);
    return result;
}
1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259
1260
1261
1262
1251
1252
1253
1254
1255
1256
1257

1258
1259
1260
1261
1262
1263
1264
1265







-
+







    } 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,
	Tk_FreeConfigOptions((char *)clientData,
		headerPtr->optionTable, NULL);
	Tcl_EventuallyFree(clientData, TCL_DYNAMIC);
    }
}

/*
 *--------------------------------------------------------------
1279
1280
1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291
1292
1293
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
1296







-
+







    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,
	    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);
1498
1499
1500
1501
1502
1503
1504
1505

1506
1507
1508
1509
1510
1511
1512
1501
1502
1503
1504
1505
1506
1507

1508
1509
1510
1511
1512
1513
1514
1515







-
+







    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    TImageInstance *instPtr;
    char buffer[100];
    XGCValues gcValues;

    sprintf(buffer, "%s get", timPtr->imageName);
    snprintf(buffer, sizeof(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;
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
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







-
+









-
+




-
+







	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",
	    snprintf(instPtr->buffer, sizeof(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.
	 * 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",
	    snprintf(instPtr->buffer, sizeof(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;
    }
1628
1629
1630
1631
1632
1633
1634
1635

1636
1637
1638
1639
1640
1641
1642
1631
1632
1633
1634
1635
1636
1637

1638
1639
1640
1641
1642
1643
1644
1645







-
+







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);
    snprintf(buffer, sizeof(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);
}

1662
1663
1664
1665
1666
1667
1668
1669

1670
1671
1672
1673
1674
1675
1676
1665
1666
1667
1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
1679







-
+







    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);
    snprintf(buffer, sizeof(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);
1821
1822
1823
1824
1825
1826
1827
1828

1829
1830
1831
1832
1833
1834
1835
1824
1825
1826
1827
1828
1829
1830

1831
1832
1833
1834
1835
1836
1837
1838







-
+







    } 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);
    snprintf(buf, sizeof(buf), "%d", val);
    Tcl_AppendResult(interp, buf, NULL);
    return TCL_OK;
}
#endif

/*
 *----------------------------------------------------------------------
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
1895
1896
1897
1898
1899
1900
1901

1902
1903
1904
1905
1906
1907
1908
1909
1910
1911






















































1912
1913
1914
1915
1916
1917
1918







-
+









-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







		} else if (actualFormat == 16) {
		    value = 0xffff & (*((short *) p));
		    p += sizeof(short);
		} else {
		    value = 0xff & *p;
		    p += 1;
		}
		sprintf(buffer, "0x%lx", value);
		snprintf(buffer, sizeof(buffer), "0x%lx", value);
		Tcl_AppendElement(interp, buffer);
	    }
	}
    }
    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 --
 *
2040
2041
2042
2043
2044
2045
2046
2047

2048
2049
2050
2051
2052
2053
2054
2055
2056

2057
2058
2059
2060
2061
2062
2063
1989
1990
1991
1992
1993
1994
1995

1996
1997
1998
1999
2000
2001
2002
2003
2004

2005
2006
2007
2008
2009
2010
2011
2012







-
+








-
+







static int
CustomOptionSet(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    TCL_UNUSED(Tk_Window),
    Tcl_Obj **value,
    char *recordPtr,
    TkSizeT internalOffset,
    int internalOffset,
    char *saveInternalPtr,
    int flags)
{
    int objEmpty;
    char *newStr, *string, *internalPtr;

    objEmpty = 0;

    if (internalOffset != TCL_INDEX_NONE) {
    if (internalOffset >= 0) {
	internalPtr = recordPtr + internalOffset;
    } else {
	internalPtr = NULL;
    }

    /*
     * See if the object is empty.
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
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







-
+






-
+




-
-
-






-
+



-
-
-




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








}

static Tcl_Obj *
CustomOptionGet(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,
    TkSizeT internalOffset)
    int internalOffset)
{
    return (Tcl_NewStringObj(*(char **)(recordPtr + internalOffset), -1));
}

static void
CustomOptionRestore(
    ClientData dummy,
    ClientData clientData,
    Tk_Window tkwin,
    char *internalPtr,
    char *saveInternalPtr)
{
    (void)dummy;
    (void)tkwin;

    *(char **)internalPtr = *(char **)saveInternalPtr;
    return;
}

static void
CustomOptionFree(
    ClientData dummy,
    ClientData clientData,
    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:
 */
Changes to generic/tkText.c.
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18










-
+







/*
 * tkText.c --
 *
 *	This module provides a big chunk of the implementation of multi-line
 *	editable text widgets for Tk. Among other things, it provides the Tcl
 *	command interfaces to text widgets. The B-tree representation of text
 *	and its actual display are implemented elsewhere.
 *
 * Copyright (c) 1992-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 * Copyright (c) 1999 by Scriptics Corporation.
 * 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.
 */

#include "tkInt.h"
#include "tkUndo.h"
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
38
39
40
41
42
43
44










45
46
47
48
49
50
51







-
-
-
-
-
-
-
-
-
-







/*
 * Used to avoid having to allocate and deallocate arrays on the fly for
 * commonly used functions. Must be > 0.
 */

#define PIXEL_CLIENTS 5

/*
 * The 'TkTextState' enum in tkText.h is used to define a type for the -state
 * option of the Text widget. These values are used as indices into the string
 * table below.
 */

static const char *const stateStrings[] = {
    "disabled", "normal", NULL
};

/*
 * The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap
 * option of the Text widget. These values are used as indices into the string
 * table below.
 */

static const char *const wrapStrings[] = {
92
93
94
95
96
97
98
99

100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125


126
127
128

129
130
131

132
133
134

135
136
137


138
139

140
141
142

143
144
145

146
147
148
149


150
151

152
153

154
155
156

157
158
159

160
161
162

163
164
165

166
167
168
169


170
171
172
173


174
175
176
177

178
179
180
181


182
183
184

185
186
187

188
189
190
191
192


193
194

195
196
197

198
199
200

201
202
203

204
205

206
207

208
209
210
211
212


213
214
215

216
217
218

219
220

221
222
223

224
225
226

227
228
229

230
231
232
233


234
235

236
237
238

239
240
241

242
243
244

245
246
247

248
249
250
251


252
253

254
255
256

257
258
259
260
261
262
263
82
83
84
85
86
87
88

89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113


114
115
116
117

118
119
120

121
122
123

124
125


126
127
128

129
130
131

132
133
134

135
136
137


138
139
140

141
142

143
144
145

146
147
148

149
150
151

152
153
154

155
156
157


158
159
160
161


162
163
164
165
166

167
168
169


170
171
172
173

174
175
176

177
178
179
180


181
182
183

184
185
186

187
188
189

190
191
192

193
194

195
196

197
198
199
200


201
202
203
204

205
206
207

208
209

210
211
212

213
214
215

216
217
218

219
220
221


222
223
224

225
226
227

228
229
230

231
232
233

234
235
236

237
238
239


240
241
242

243
244
245

246
247
248
249
250
251
252
253







-
+



-
+




















-
-
+
+


-
+


-
+


-
+

-
-
+
+

-
+


-
+


-
+


-
-
+
+

-
+

-
+


-
+


-
+


-
+


-
+


-
-
+
+


-
-
+
+



-
+


-
-
+
+


-
+


-
+



-
-
+
+

-
+


-
+


-
+


-
+

-
+

-
+



-
-
+
+


-
+


-
+

-
+


-
+


-
+


-
+


-
-
+
+

-
+


-
+


-
+


-
+


-
+


-
-
+
+

-
+


-
+







 * 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 internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetLineStartEnd(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr,
			    TkSizeT internalOffset);
			    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, TCL_INDEX_NONE,
	offsetof(TkText, autoSeparators),
	"AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1,
	Tk_Offset(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),
	DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border),
	0, DEF_TEXT_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth",
	NULL, 0, -1, 0, "-borderwidth",
	TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BOOLEAN, "-blockcursor", "blockCursor",
	"BlockCursor", DEF_TEXT_BLOCK_CURSOR, TCL_INDEX_NONE,
	offsetof(TkText, insertCursorType), 0, 0, 0},
	"BlockCursor", DEF_TEXT_BLOCK_CURSOR, -1,
	Tk_Offset(TkText, insertCursorType), 0, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_TEXT_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(TkText, 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, TCL_INDEX_NONE, offsetof(TkText, cursor),
	DEF_TEXT_CURSOR, -1, Tk_Offset(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,
	 NULL, -1, Tk_Offset(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},
	"ExportSelection", DEF_TEXT_EXPORT_SELECTION, -1,
	Tk_Offset(TkText, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_TEXT_FONT, TCL_INDEX_NONE, offsetof(TkText, tkfont), 0, 0,
	DEF_TEXT_FONT, -1, Tk_Offset(TkText, tkfont), 0, 0,
	TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_TEXT_FG, TCL_INDEX_NONE, offsetof(TkText, fgColor), 0,
	DEF_TEXT_FG, -1, Tk_Offset(TkText, fgColor), 0,
	0, 0},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_TEXT_HEIGHT, TCL_INDEX_NONE, offsetof(TkText, height), 0, 0, 0},
	DEF_TEXT_HEIGHT, -1, Tk_Offset(TkText, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_TEXT_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(TkText, highlightBgColorPtr),
	-1, Tk_Offset(TkText, highlightBgColorPtr),
	0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_TEXT_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkText, highlightColorPtr),
	DEF_TEXT_HIGHLIGHT, -1, Tk_Offset(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},
	"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,
	TCL_INDEX_NONE, offsetof(TkText, inactiveSelBorder),
	DEF_TEXT_INACTIVE_SELECT_BG_COLOR,
	-1, Tk_Offset(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),
	-1, Tk_Offset(TkText, insertBorder),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_TEXT_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(TkText, insertBorderWidth), 0,
	"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, TCL_INDEX_NONE, offsetof(TkText, insertOffTime),
	DEF_TEXT_INSERT_OFF_TIME, -1, Tk_Offset(TkText, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_TEXT_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(TkText, insertOnTime),
	DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(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},
	DEF_TEXT_INSERT_UNFOCUSSED, -1, Tk_Offset(TkText, insertUnfocussed),
	TK_OPTION_ENUM_VAR, insertUnfocussedStrings, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_TEXT_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(TkText, insertWidth),
	DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth),
	0, 0, 0},
    {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo",
	DEF_TEXT_MAX_UNDO, TCL_INDEX_NONE, offsetof(TkText, maxUndo),
	DEF_TEXT_MAX_UNDO, -1, Tk_Offset(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,
	DEF_TEXT_PADX, -1, Tk_Offset(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},
	DEF_TEXT_PADY, -1, Tk_Offset(TkText, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_TEXT_RELIEF, TCL_INDEX_NONE, offsetof(TkText, relief), 0, 0, 0},
	DEF_TEXT_RELIEF, -1, Tk_Offset(TkText, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_TEXT_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkText, selBorder),
	DEF_TEXT_SELECT_COLOR, -1, Tk_Offset(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_Offset(TkText, selBorderWidthPtr),
	Tk_Offset(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),
	DEF_TEXT_SELECT_FG_COLOR, -1, Tk_Offset(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},
	DEF_TEXT_SET_GRID, -1, Tk_Offset(TkText, setGrid), 0, 0, 0},
    {TK_OPTION_PIXELS, "-spacing1", "spacing1", "Spacing",
	DEF_TEXT_SPACING1, TCL_INDEX_NONE, offsetof(TkText, spacing1),
	DEF_TEXT_SPACING1, -1, Tk_Offset(TkText, spacing1),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_PIXELS, "-spacing2", "spacing2", "Spacing",
	DEF_TEXT_SPACING2, TCL_INDEX_NONE, offsetof(TkText, spacing2),
	DEF_TEXT_SPACING2, -1, Tk_Offset(TkText, spacing2),
	0, 0 , TK_TEXT_LINE_GEOMETRY },
    {TK_OPTION_PIXELS, "-spacing3", "spacing3", "Spacing",
	DEF_TEXT_SPACING3, TCL_INDEX_NONE, offsetof(TkText, spacing3),
	DEF_TEXT_SPACING3, -1, Tk_Offset(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,
	 NULL, -1, Tk_Offset(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},
	DEF_TEXT_STATE, -1, Tk_Offset(TkText, state),
	0, &tkStateStrings[1], 0},
    {TK_OPTION_STRING, "-tabs", "tabs", "Tabs",
	DEF_TEXT_TABS, offsetof(TkText, tabOptionPtr), TCL_INDEX_NONE,
	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, TCL_INDEX_NONE, offsetof(TkText, tabStyle),
	DEF_TEXT_TABSTYLE, -1, Tk_Offset(TkText, tabStyle),
	0, tabStyleStrings, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_TEXT_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(TkText, 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, TCL_INDEX_NONE, offsetof(TkText, undo),
	DEF_TEXT_UNDO, -1, Tk_Offset(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,
	DEF_TEXT_WIDTH, -1, Tk_Offset(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},
	DEF_TEXT_WRAP, -1, Tk_Offset(TkText, wrapMode),
	TK_OPTION_ENUM_VAR, wrapStrings, TK_TEXT_LINE_GEOMETRY},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_TEXT_XSCROLL_COMMAND, TCL_INDEX_NONE, offsetof(TkText, xScrollCmd),
	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, TCL_INDEX_NONE, offsetof(TkText, yScrollCmd),
	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
265
266
267
268
269
270
271

272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

291
292
293

294
295
296
297
298
299
300
301







-
+


-
+















-
+


-
+







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);
			    int matchOffset, int matchLength);
typedef int		SearchLineIndexProc(Tcl_Interp *interp,
			    Tcl_Obj *objPtr, struct SearchSpec *searchSpecPtr,
			    int *linePosPtr, TkSizeT *offsetPosPtr);
			    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. */
    TkSizeT startOffset;		/* Index in first line to start at. */
    int 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
    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
351
352
353
354
355
356
357


358
359
360
361
362
363
364
365
366







-
-
+
+







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		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,
406
407
408
409
410
411
412
413
414


415
416
417
418
419
420
421
396
397
398
399
400
401
402


403
404
405
406
407
408
409
410
411







-
-
+
+







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		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.
548
549
550
551
552
553
554

555
556
557
558
559
560
561
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552







+







	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;
	sharedPtr->imageCount = 0;
    }

    /*
     * Add the new widget to the shared list.
     */

    textPtr->sharedTextPtr = sharedPtr;
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
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







-
+









-
+







    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)
    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, Tk_NewWindowObj(textPtr->tkwin));
    Tcl_SetObjResult(interp, TkNewWindowObj(textPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TextWidgetObjCmd --
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
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







-
-
-
-
+
+
+
+











-
+







	    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_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, textPtr,
	    Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr,
		    textPtr->optionTable, objv[2], textPtr->tkwin);

	    if (objPtr == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    Tcl_SetObjResult(interp, objPtr);
822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
813
814
815
816
817
818
819

820
821
822
823
824
825
826
827







-
+







		" <, <=, ==, >=, >, 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,
	    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;
	    }
860
861
862
863
864
865
866
867
868


869
870
871
872
873
874
875
851
852
853
854
855
856
857


858
859
860
861
862
863
864
865
866







-
-
+
+







	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);
	    int length;
	    const char *option = Tcl_GetStringFromObj(objv[i], &length);
	    char c;

	    if (length < 2 || option[0] != '-') {
		goto badOption;
	    }
	    c = option[1];
	    if (c == 'c' && !strncmp("-chars", option, length)) {
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
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







-
+











-
+











-
+







-
+







	    } else {
		goto badOption;
	    }

	countDone:
	    found++;
	    if (found == 1) {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(value));
		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_NewWideIntObj(value));
		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_NewWideIntObj(value));
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(value));
	} else if (found > 1) {
	    Tcl_SetObjResult(interp, objPtr);
	}
	break;

    badOption:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad option \"%s\": must be -chars, -displaychars, "
		"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:
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
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







-
-
-
-
-
+
+
+
+
+















-
+















-
+




-
+







	    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_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;
	TkSizeT length;
	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 = TkGetStringFromObj(objv[i], &length);
	    name = Tcl_GetStringFromObj(objv[i], &length);
	    if (length > 1 && name[0] == '-') {
		if (strncmp("-displaychars", name, length) == 0) {
		    i++;
		    visible = 1;
		    name = TkGetStringFromObj(objv[i], &length);
		    name = Tcl_GetStringFromObj(objv[i], &length);
		}
		if ((i < objc-1) && (length == 2) && !strcmp("--", name)) {
		    i++;
		}
	    }
	}

1749
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1740
1741
1742
1743
1744
1745
1746

1747
1748
1749
1750
1751
1752
1753
1754







-
+







	    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));
			TkNewWindowObj(tPtr->tkwin));
	    }
	    tPtr = tPtr->next;
	}
	Tcl_SetObjResult(interp, peersObj);
    }
    }

2280
2281
2282
2283
2284
2285
2286


2287



2288
2289
2290
2291
2292
2293
2294
2271
2272
2273
2274
2275
2276
2277
2278
2279

2280
2281
2282
2283
2284
2285
2286
2287
2288
2289







+
+
-
+
+
+







	    || (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->tabStyle == TK_TEXT_TABSTYLE_TABULAR)
	    || (textPtr->selTagPtr->tabStyle == TK_TEXT_TABSTYLE_WORDPROCESSOR)
	    || (textPtr->selTagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
	    || (textPtr->selTagPtr->wrapMode == TEXT_WRAPMODE_CHAR)
	    || (textPtr->selTagPtr->wrapMode == TEXT_WRAPMODE_NONE)
	    || (textPtr->selTagPtr->wrapMode == TEXT_WRAPMODE_WORD)) {
	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)
2627
2628
2629
2630
2631
2632
2633
2634

2635
2636
2637
2638
2639

2640
2641
2642
2643
2644
2645
2646
2622
2623
2624
2625
2626
2627
2628

2629
2630
2631
2632
2633

2634
2635
2636
2637
2638
2639
2640
2641







-
+




-
+







				 * 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;
    int length;
    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];
    const char *string = TkGetStringFromObj(stringPtr, &length);
    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
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
2769
2770
2771
2772
2773
2774
2775



2776
2777
2778
2779
2780
2781
2782
2783
2784
2785




2786
2787
2788
2789
2790
2791
2792







-
-
-










-
-
-
-







    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);
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

















-
-
-
-





-
-
-
-







    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);
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
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







-
+








-
+
+


-
-
-
-
+
-
-
-
-
-
-
+
-







		     */

		    TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line,
			    byteIndex, &indexTmp);
		    TkTextSetYView(tPtr, &indexTmp, 0);
		}
	    } else {
		TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line,
		TkTextMakeByteIndex(sharedTextPtr->tree, NULL, 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
		 * involves the TOP line of the screen. That said,
		 * the following call adjusts to both.
		 */

		if (tPtr->start != NULL) {
		    int start;
		    TkTextIndex indexStart;

		TkTextIndexAdjustToStartEnd(tPtr, &indexTmp, 0);
		    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);
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
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







-
+


-
+


-
+





-
+
-







 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
TextFetchSelection(
    ClientData clientData,	/* Information about text widget. */
    TkSizeT offset,			/* Offset within selection of first character
    int 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,
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TkText *textPtr = (TkText *)clientData;
    TkTextIndex eof;
    int count, chunkSize;
    int count, chunkSize, offsetInSeg;
    TkSizeT offsetInSeg;
    TkTextSearch search;
    TkTextSegment *segPtr;

    if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
	return -1;
    }

3486
3487
3488
3489
3490
3491
3492
3493
3494


3495
3496
3497
3498
3499
3500
3501
3423
3424
3425
3426
3427
3428
3429


3430
3431
3432
3433
3434
3435
3436
3437
3438







-
-
+
+








	while (1) {
	    if (maxBytes == 0) {
		goto fetchDone;
	    }
	    segPtr = TkTextIndexToSeg(&textPtr->selIndex, &offsetInSeg);
	    chunkSize = segPtr->size - offsetInSeg;
	    if (chunkSize > (int)maxBytes) {
		chunkSize = (int)maxBytes;
	    if (chunkSize > maxBytes) {
		chunkSize = maxBytes;
	    }
	    if (textPtr->selIndex.linePtr == search.curIndex.linePtr) {
		int leftInRange;

		leftInRange = search.curIndex.byteIndex
			- textPtr->selIndex.byteIndex;
		if (leftInRange < chunkSize) {
3553
3554
3555
3556
3557
3558
3559
3560

3561
3562
3563
3564
3565
3566
3567
3490
3491
3492
3493
3494
3495
3496

3497
3498
3499
3500
3501
3502
3503
3504







-
+








void
TkTextLostSelection(
    ClientData clientData)	/* Information about text widget. */
{
    TkText *textPtr = (TkText *)clientData;

    if (Tk_AlwaysShowSelection(textPtr->tkwin)) {
    if (TkpAlwaysShowSelection(textPtr->tkwin)) {
	TkTextIndex start, end;

	if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
	    return;
	}

	/*
3611
3612
3613
3614
3615
3616
3617
3618

3619
3620
3621
3622
3623
3624
3625
3548
3549
3550
3551
3552
3553
3554

3555
3556
3557
3558
3559
3560
3561
3562







-
+







    TkText *textPtr)
{
    /*
     * Send an event that the selection changed. This is equivalent to:
     *     event generate $textWidget <<Selection>>
     */

    Tk_SendVirtualEvent(textPtr->tkwin, "Selection", NULL);
    TkSendVirtualEvent(textPtr->tkwin, "Selection", NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * TextBlinkProc --
 *
3986
3987
3988
3989
3990
3991
3992
3993

3994
3995
3996
3997
3998
3999
4000
3923
3924
3925
3926
3927
3928
3929

3930
3931
3932
3933
3934
3935
3936
3937







-
+







/*
 *----------------------------------------------------------------------
 *
 * TextSearchGetLineIndex --
 *
 *	Extract a row, text offset index position from an objPtr
 *
 *	This means we ignore any embedded windows/images and elidden text
 *	This means we ignore any embedded windows/images and elided text
 *	(unless we are searching that).
 *
 * Results:
 *	Standard Tcl error code (with a message in the interpreter on error
 *	conditions).
 *
 *	The offset placed in offsetPosPtr is a utf-8 char* byte index for
4011
4012
4013
4014
4015
4016
4017
4018

4019
4020
4021
4022
4023
4024
4025
3948
3949
3950
3951
3952
3953
3954

3955
3956
3957
3958
3959
3960
3961
3962







-
+








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
    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);
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
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







-
+












-
+




-
+



-
-
+






-
+




-
+







 *----------------------------------------------------------------------
 *
 * TextSearchIndexInLine --
 *
 *	Find textual index of 'byteIndex' in the searchable characters of
 *	'linePtr'.
 *
 *	This means we ignore any embedded windows/images and elidden text
 *	This means we ignore any embedded windows/images and elided text
 *	(unless we are searching that).
 *
 * Results:
 *	The returned index is a utf-8 char* byte index for exact searches, and
 *	a Unicode character index for regexp searches.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
static int
TextSearchIndexInLine(
    const SearchSpec *searchSpecPtr,
				/* Search parameters. */
    TkTextLine *linePtr,	/* The line we're looking at. */
    TkSizeT byteIndex)		/* Index into the line. */
    int byteIndex)		/* Index into the line. */
{
    TkTextSegment *segPtr;
    TkTextIndex curIndex;
    TkSizeT index;
    int leftToScan;
    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 + 1 > 1;
	    leftToScan > 0;
	    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 (leftToScan < segPtr->size) {
		if (searchSpecPtr->exact) {
		    index += leftToScan;
		} else {
		    index += Tcl_NumUtfChars(segPtr->body.chars, leftToScan);
		}
	    } else if (searchSpecPtr->exact) {
		index += segPtr->size;
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
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







-
+

-
+


-
+














-
+






-
+

















-
+







    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
    int 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
    int matchLength)		/* Length also in bytes/chars as per search
				 * type. */
{
    TkSizeT numChars;
    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 + 1 >= searchSpecPtr->stopOffset + 1)) {
		(matchOffset >= searchSpecPtr->stopOffset)) {
	    return 0;
	}
    }

    /*
     * Calculate the character count, which may need augmenting if there are
     * embedded windows or elidden text.
     * embedded windows or elided text.
     */

    if (searchSpecPtr->exact) {
	const char *startOfLine = Tcl_GetString(theLine);

	numChars = Tcl_NumUtfChars(startOfLine + matchOffset, matchLength);
    } else {
	numChars = matchLength;
    }

    /*
     * If we're using strict limits checking, ensure that the match with its
     * full length fits inside the given range.
     */

    if (searchSpecPtr->strictLimits && lineNum == searchSpecPtr->stopLine) {
	if (searchSpecPtr->backwards ^
		((matchOffset + numChars + 1) > searchSpecPtr->stopOffset + 1)) {
		((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
4296
4297
4298
4299
4300
4301
4302

4303
4304
4305
4306
4307
4308
4309
4310







-
+







		if (searchSpecPtr->exact) {
		    matchOffset += segPtr->size;
		} else {
		    matchOffset += Tcl_NumUtfChars(segPtr->body.chars, -1);
		}
	    } else {
		if (searchSpecPtr->exact) {
		    leftToScan -= (int)segPtr->size;
		    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
4398
4399
4400
4401
4402
4403
4404

4405
4406
4407
4408
4409
4410
4411
4412







-
+







    }

    /*
     * Now store the count result, if it is wanted.
     */

    if (searchSpecPtr->varPtr != NULL) {
	Tcl_Obj *tmpPtr = Tcl_NewWideIntObj(numChars);
	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;
4535
4536
4537
4538
4539
4540
4541
4542

4543
4544
4545
4546
4547
4548
4549
4471
4472
4473
4474
4475
4476
4477

4478
4479
4480
4481
4482
4483
4484
4485







-
+







	}
    }

    /*
     * Parse the elements of the list one at a time to fill in the array.
     */

    tabArrayPtr = (TkTextTabArray *)ckalloc(offsetof(TkTextTabArray, tabs)
    tabArrayPtr = (TkTextTabArray *)ckalloc(Tk_Offset(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;

4749
4750
4751
4752
4753
4754
4755
4756

4757
4758
4759
4760
4761
4762

4763
4764
4765
4766
4767
4768
4769
4685
4686
4687
4688
4689
4690
4691

4692
4693
4694
4695
4696
4697

4698
4699
4700
4701
4702
4703
4704
4705







-
+





-
+







	return TCL_ERROR;
    }
    arg++;
    atEnd = 0;
    if (objc == arg) {
	TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
    } else {
	TkSizeT length;
	int length;
	const char *str;

	if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
	    return TCL_ERROR;
	}
	str = TkGetStringFromObj(objv[arg], &length);
	str = Tcl_GetStringFromObj(objv[arg], &length);
	if (strncmp(str, "end", length) == 0) {
	    atEnd = 1;
	}
    }
    if (TkTextIndexCmp(&index1, &index2) >= 0) {
	return TCL_OK;
    }
5071
5072
5073
5074
5075
5076
5077
5078

5079
5080
5081
5082
5083
5084
5085
5007
5008
5009
5010
5011
5012
5013

5014
5015
5016
5017
5018
5019
5020
5021







-
+







    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);
	int 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);
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
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







-
-




+
+
+
+



















-
-
-
-
-
+
-
-
+
-
-
-
-
-
-

-







 */

static int
TextEditUndo(
    TkText *textPtr)		/* Overall information about text widget. */
{
    int status;
    Tcl_Obj *cmdObj;
    int code;

    if (!textPtr->sharedTextPtr->undo) {
	return TCL_OK;
    }

    if (textPtr->sharedTextPtr->autoSeparators) {
	TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack);
    }

    /*
     * Turn off the undo feature while we revert a compound action, setting
     * the dirty handling mode to undo for the duration (unless it is
     * 'fixed').
     */

    textPtr->sharedTextPtr->undo = 0;
    if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) {
	textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_UNDO;
    }

    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.
     */

    if (textPtr->sharedTextPtr->autoSeparators) {
    cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s",
            Tk_PathName(textPtr->tkwin));
	TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack);
    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;
}

/*
 *----------------------------------------------------------------------
 *
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5106
5107
5108
5109
5110
5111
5112


5113
5114
5115
5116
5117
5118
5119







-
-







 */

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
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
5128
5129
5130
5131
5132
5133
5134

















5135
5136
5137
5138
5139
5140
5141







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








    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 --
5430
5431
5432
5433
5434
5435
5436
5437

5438
5439
5440
5441
5442
5443
5444
5337
5338
5339
5340
5341
5342
5343

5344
5345
5346
5347
5348
5349
5350
5351







-
+








    TkTextMakeByteIndex(indexPtr1->tree, textPtr,
	    TkBTreeLinesTo(textPtr, indexPtr1->linePtr),
	    indexPtr1->byteIndex, &tmpIndex);

    if (TkTextIndexCmp(indexPtr1, indexPtr2) < 0) {
	while (1) {
	    TkSizeT offset;
	    int 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
5485
5486
5487
5488
5489
5490
5491
5492

5493
5494
5495
5496
5497
5498
5499
5392
5393
5394
5395
5396
5397
5398

5399
5400
5401
5402
5403
5404
5405
5406







-
+







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);
	TkSendVirtualEvent(textPtr->tkwin, "Modified", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GenerateUndoStackEvent --
5515
5516
5517
5518
5519
5520
5521
5522

5523
5524
5525
5526
5527
5528
5529
5422
5423
5424
5425
5426
5427
5428

5429
5430
5431
5432
5433
5434
5435
5436







-
+







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);
	TkSendVirtualEvent(textPtr->tkwin, "UndoStack", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * UpdateDirtyFlag --
5613
5614
5615
5616
5617
5618
5619
5620

5621
5622
5623
5624
5625
5626
5627
5520
5521
5522
5523
5524
5525
5526

5527
5528
5529
5530
5531
5532
5533
5534







-
+







	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_BackgroundError(textPtr->interp);
    }
    Tcl_Release((ClientData) textPtr->interp);
    Tcl_DecrRefCount(textPtr->afterSyncCmd);
    textPtr->afterSyncCmd = NULL;
}

/*
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
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







-
+




















-
-
-
+
+
+







{
    /*
     * For exact searches these are utf-8 char* offsets, for regexp searches
     * they are Unicode char offsets.
     */

    int firstOffset, lastOffset;
    TkSizeT matchOffset,  matchLength;
    int 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 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
5731
5732
5733
5734
5735
5736
5737

5738
5739
5740
5741
5742
5743
5744
5745







-
+








	/*
	 * 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);
	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.
	 */
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
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







-
+











-
+













-
+









-
+



-
+







		/*
		 * 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) {
		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 + 1 < (TkSizeT)lastOffset + 1) {
		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 = TCL_INDEX_NONE;
	matchOffset = -1;

	if (searchSpecPtr->exact) {
	    int maxExtraLines = 0;
	    const char *startOfLine = Tcl_GetString(theLine);

	    CLANG_ASSERT(pattern);
	    do {
		int ch;
		const char *p;
		TkSizeT lastFullLine = lastOffset;
		int lastFullLine = lastOffset;

		if (firstNewLine == -1) {
		    if (searchSpecPtr->strictLimits
			    && (firstOffset + matchLength + 1 > (TkSizeT)lastOffset + 1)) {
			    && (firstOffset + matchLength > lastOffset)) {
			/*
			 * Not enough characters to match.
			 */

			break;
		    }

6081
6082
6083
6084
6085
6086
6087
6088

6089
6090
6091
6092
6093
6094
6095
5988
5989
5990
5991
5992
5993
5994

5995
5996
5997
5998
5999
6000
6001
6002







-
+







			    p = startOfLine + skipFirst;

			    /*
			     * Use the fact that 'matchLength = patLength' for
			     * exact searches.
			     */

			    if ((TkSizeT)lastTotal - skipFirst + 1 >= matchLength + 1) {
			    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, matchLength)) {
6163
6164
6165
6166
6167
6168
6169
6170

6171
6172
6173
6174
6175
6176
6177
6070
6071
6072
6073
6074
6075
6076

6077
6078
6079
6080
6081
6082
6083
6084







-
+







			    alreadySearchOffset -= (matchLength ? matchLength : 1);
                            if (alreadySearchOffset < 0) {
                                break;
                            }
			}
		    } else {
                        firstOffset = matchLength ? p - startOfLine + matchLength
                                                  : p - startOfLine + (TkSizeT)1;
                                                  : p - startOfLine + 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.
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
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







-
+

















-
+

-
+















-
+







	    int maxExtraLines = 0;
	    int matches = 0;
	    int lastNonOverlap = -1;

	    do {
		Tcl_RegExpInfo info;
		int match;
		TkSizeT lastFullLine = lastOffset;
		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 == (TkSizeT) (lastOffset - firstOffset)))) {
			&& (info.matches[0].end == lastOffset-firstOffset))) {
		    int extraLines = 0;
		    TkSizeT prevFullLine;
		    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 == TCL_INDEX_NONE) {
		    if (info.extendStart < 0) {
			/*
			 * No multi-line match is possible.
			 */

			break;
		    }

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
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







-
-
-
+
+
+










-
+







			 * 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) {
				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 + 1 >= (TkSizeT) lastOffset + 1)) {
			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
6313
6314
6315
6316
6317
6318
6319


6320
6321
6322
6323
6324
6325
6326
6327
6328







-
-
+
+







				    - info.matches[0].start;

			    if (lastNonOverlap != -1) {
				/*
				 * Possible overlap or enclosure.
				 */

				if ((TkSizeT)thisOffset - lastNonOverlap >=
					lastBackwardsMatchOffset + matchLength + 1){
				if (thisOffset - lastNonOverlap >=
					lastBackwardsMatchOffset + matchLength){
				    /*
				     * Totally encloses previous match, so
				     * forget the previous match.
				     */

				    lastBackwardsLineMatch = -1;
				} else if ((thisOffset - lastNonOverlap)
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
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







-
+

-
+


-
+

















-
-
-
+
+
+

-
+







		/*
		 * 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 ||
		if (matchOffset == -1 ||
			((searchSpecPtr->all || searchSpecPtr->backwards)
			&& (((TkSizeT)firstOffset + 1 < matchOffset + 1)
			&& ((firstOffset < matchOffset)
			|| ((firstOffset + info.matches[0].end
				- info.matches[0].start)
				> matchOffset + matchLength)))) {
				> (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));
			    int *newArray = (int *)
				    ckalloc(4 * matchNum * sizeof(int));
			    memcpy(newArray, storeMatch, matchNum*sizeof(int));
			    memcpy(newArray + 2*matchNum, storeLength,
				    matchNum * sizeof(TkSizeT));
				    matchNum * sizeof(int));
			    if (storeMatch != smArray) {
				ckfree(storeMatch);
			    }
			    matchNum *= 2;
			    storeMatch = newArray;
			    storeLength = newArray + matchNum;
			}
6550
6551
6552
6553
6554
6555
6556
6557

6558
6559
6560
6561
6562
6563
6564
6457
6458
6459
6460
6461
6462
6463

6464
6465
6466
6467
6468
6469
6470
6471







-
+








		    /*
		     * 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
		    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
6514
6515
6516
6517
6518
6519
6520


6521
6522
6523
6524
6525
6526
6527
6528
6529







-
-
+
+







			 * 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) {
		    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];
6656
6657
6658
6659
6660
6661
6662
6663

6664
6665
6666
6667
6668
6669
6670
6563
6564
6565
6566
6567
6568
6569

6570
6571
6572
6573
6574
6575
6576
6577







-
+







	 * 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)
	if ((lastBackwardsLineMatch == -1) && (matchOffset >= 0)
		&& !searchSpecPtr->all) {
	    searchSpecPtr->foundMatchProc(lineNum, searchSpecPtr, lineInfo,
		    theLine, matchOffset, matchLength);
	    goto searchDone;
	}

	/*
6775
6776
6777
6778
6779
6780
6781
6782

6783
6784
6785
6786
6787
6788
6789
6790

6791
6792
6793
6794
6795
6796
6797
6682
6683
6684
6685
6686
6687
6688

6689
6690
6691
6692
6693
6694
6695
6696

6697
6698
6699
6700
6701
6702
6703
6704







-
+







-
+







 */

static Tcl_Obj *
GetLineStartEnd(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    TkSizeT internalOffset)		/* Offset within *recordPtr containing the
    int 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));
    return Tcl_NewIntObj(1 + TkBTreeLinesTo(NULL, linePtr));
}

/*
 *----------------------------------------------------------------------
 *
 * SetLineStartEnd --
 *
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
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







-
+








-
-
+
+







    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
    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 != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + internalOffset;
    if (internalOffset >= 0) {
	internalPtr = recordPtr + internalOffset;
    } else {
	internalPtr = NULL;
    }

    if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
	*value = NULL;
    } else {
6934
6935
6936
6937
6938
6939
6940
6941

6942
6943
6944
6945
6946
6947
6948
6841
6842
6843
6844
6845
6846
6847

6848
6849
6850
6851
6852
6853
6854
6855







-
+







    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];
    char buf[TK_POS_CHARS];
    Tcl_CmdInfo info;

    if (objc < 3) {
	return TCL_ERROR;
    }

    if (Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) == 0) {
Changes to generic/tkText.h.
161
162
163
164
165
166
167
168

169
170


171
172
173




174
175
176
177
178
179
180
161
162
163
164
165
166
167

168
169
170
171
172



173
174
175
176
177
178
179
180
181
182
183







-
+


+
+
-
-
-
+
+
+
+







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
    int size;			/* Size of this segment (# of bytes of index
				 * space it occupies). */
    union {
	/* The TKFLEXARRAY macro - unfortunately - doesn't work inside a union. */
#if defined(__GNUC__) && (__GNUC__ > 2)
	char chars[TKFLEXARRAY];		/* Characters that make up character info.
				 * Actual length varies to hold as many
				 * characters as needed.*/
	char chars[0];		/* Characters that make up character info. */
#else				/* Actual length varies to hold as many */
	char chars[1];		/* characters as needed. See [dacd18294b] */
#endif
	TkTextToggle toggle;	/* Information about tag toggle. */
	TkTextMark mark;	/* Information about mark. */
	TkTextEmbWindow ew;	/* Information about embedded window. */
	TkTextEmbImage ei;	/* Information about embedded image. */
    } body;
} TkTextSegment;

528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
531
532
533
534
535
536
537








538

539
540
541
542
543
544
545
546







-
-
-
-
-
-
-
-

-
+







} 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. */
    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
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







-
+




+













-
-







				 * 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
    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. */
    int imageCount;		/* Used for creating unique image names. */

    /*
     * 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
787
788
789
790
791
792
793
794

795
796
797
798
799
800
801
781
782
783
784
785
786
787

788
789
790
791
792
793
794
795







-
+







				 * 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
    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
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
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







-
+








-
-
+
+








/*
 * 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);
			    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, TkSizeT offset, int maxX,
			    TkSizeT maxChars, int noCharsYet, TkWrapMode wrapMode,
			    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
1013
1014
1015
1016
1017
1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1007
1008
1009
1010
1011
1012
1013

1014
1015
1016
1017
1018
1019
1020
1021







-
+







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 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);
1056
1057
1058
1059
1060
1061
1062
1063

1064
1065
1066
1067
1068
1069
1070
1050
1051
1052
1053
1054
1055
1056

1057
1058
1059
1060
1061
1062
1063
1064







-
+







			    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,
			    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,
1102
1103
1104
1105
1106
1107
1108
1109

1110
1111
1112
1113
1114
1115
1116
1096
1097
1098
1099
1100
1101
1102

1103
1104
1105
1106
1107
1108
1109
1110







-
+







			    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);
			    int *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);
1166
1167
1168
1169
1170
1171
1172


1173
1174
1175
1176
1177
1178
1179
1180
1181
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177







+
+









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);
MODULE_SCOPE int        TkTextIndexAdjustToStartEnd(TkText *textPtr,
			    TkTextIndex *indexPtr, int err);
#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
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
    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
136
137
138
139
140
141
142




143
144
145
146
147
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))
#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, TkSizeT index);
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,
497
498
499
500
501
502
503
504

505
506
507
508
509
510
511
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511







-
+







 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkSizeT
int
TkBTreeEpoch(
    TkTextBTree tree)		/* Tree to get epoch for. */
{
    BTree *treePtr = (BTree *) tree;
    return treePtr->stateEpoch;
}

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
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







-
+

















+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+







 *----------------------------------------------------------------------
 */

static void
AdjustStartEndRefs(
    BTree *treePtr,		/* The entire B-tree. */
    TkText *textPtr,		/* The text widget for which we want to adjust
				 * it's start and end cache. */
				 * its start and end cache. */
    int action)			/* Action to perform. */
{
    if (action & TEXT_REMOVE_REFS) {
	int i = 0;
	int count = 0;

	while (i < treePtr->startEndCount) {
	    if (i != count) {
		treePtr->startEnd[count] = treePtr->startEnd[i];
		treePtr->startEndRef[count] = treePtr->startEndRef[i];
	    }
	    if (treePtr->startEndRef[i] != textPtr) {
		count++;
	    }
	    i++;
	}
	treePtr->startEndCount = count;
	if (count > 0) {
	treePtr->startEnd = (TkTextLine **)ckrealloc(treePtr->startEnd,
		sizeof(TkTextLine *) * count);
	treePtr->startEndRef = (TkText **)ckrealloc(treePtr->startEndRef,
		sizeof(TkText *) * count);
	    treePtr->startEnd = (TkTextLine**)ckrealloc(treePtr->startEnd,
		    sizeof(TkTextLine*) * count);
	    treePtr->startEndRef = (TkText**)ckrealloc(treePtr->startEndRef,
		    sizeof(TkText*) * count);
	}
	else {
	    ckfree(treePtr->startEndRef);
	    treePtr->startEndRef = NULL;
	    ckfree(treePtr->startEnd);
	    treePtr->startEnd = NULL;
	}
    }
    if ((action & TEXT_ADD_REFS)
	    && (textPtr->start != NULL || textPtr->end != NULL)) {
	int count;

	if (textPtr->start != NULL) {
	    treePtr->startEndCount++;
1017
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
1025
1026
1027
1028
1029
1030
1031

1032
1033
1034
1035
1036
1037
1038
1039







-
+







    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. */
    int 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;
1186
1187
1188
1189
1190
1191
1192
1193

1194
1195
1196
1197
1198
1199
1200

1201
1202
1203
1204
1205
1206
1207
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;
    TkSizeT count = indexPtr->byteIndex;
    int count = indexPtr->byteIndex;

    linePtr = indexPtr->linePtr;
    prevPtr = NULL;
    segPtr = linePtr->segPtr;

    while (segPtr != NULL) {
	if (segPtr->size + 1 > count + 1) {
	if (segPtr->size > count) {
	    if (count == 0) {
		return prevPtr;
	    }
	    segPtr = segPtr->typePtr->splitProc(segPtr, count);
	    if (prevPtr == NULL) {
		indexPtr->linePtr->segPtr = segPtr;
	    } else {
1723
1724
1725
1726
1727
1728
1729




















1730
1731
1732
1733
1734
1735
1736
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    linePtr->pixels[2 * pixelReference] < pixels;
	    linePtr = linePtr->nextPtr) {
	if (linePtr == NULL) {
	    Tcl_Panic("TkBTreeFindPixelLine ran out of lines");
	}
	pixels -= linePtr->pixels[2 * pixelReference];
    }

    /*
     * Check for any start/end offset for this text widget.
     */

    if (textPtr->start != NULL) {
	int lineBoundary = TkBTreeLinesTo(NULL, textPtr->start);

	if (TkBTreeLinesTo(NULL, linePtr) < lineBoundary) {
	    linePtr = TkBTreeFindLine(tree, NULL, lineBoundary);
	}
    }
    if (textPtr->end != NULL) {
	int lineBoundary = TkBTreeLinesTo(NULL, textPtr->end);

	if (TkBTreeLinesTo(NULL, linePtr) > lineBoundary) {
	    linePtr = TkBTreeFindLine(tree, NULL, lineBoundary);
	}
    }

    if (pixelOffset != NULL && linePtr != NULL) {
	*pixelOffset = pixels;
    }
    return linePtr;
}

/*
1874
1875
1876
1877
1878
1879
1880
1881

1882
1883
1884
1885
1886
1887
1888
1902
1903
1904
1905
1906
1907
1908

1909
1910
1911
1912
1913
1914
1915
1916







-
+







 * TkBTreePixelsTo --
 *
 *	Given a pointer to a line in a B-tree, return the numerical pixel
 *	index of the top of that line (i.e. the result does not include the
 *	height of the given line).
 *
 *	Since the last line of text (the artificial one) has zero height by
 *	defintion, calling this with the last line will return the total
 *	definition, calling this with the last line will return the total
 *	number of pixels in the widget.
 *
 * Results:
 *	The result is the pixel height of the top of the given line.
 *
 * Side effects:
 *	None.
2650
2651
2652
2653
2654
2655
2656
2657

2658
2659
2660
2661
2662
2663
2664
2678
2679
2680
2681
2682
2683
2684

2685
2686
2687
2688
2689
2690
2691
2692







-
+







				 * 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;
    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.
     */
2746
2747
2748
2749
2750
2751
2752
2753

2754
2755
2756
2757
2758
2759
2760
2774
2775
2776
2777
2778
2779
2780

2781
2782
2783
2784
2785
2786
2787
2788







-
+







				 * 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;
    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.
3240
3241
3242
3243
3244
3245
3246
3247

3248
3249
3250
3251
3252
3253
3254
3268
3269
3270
3271
3272
3273
3274

3275
3276
3277
3278
3279
3280
3281
3282







-
+







     * 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) <= indexPtr->byteIndex;
	    index += segPtr->size, segPtr = segPtr->nextPtr) {
	if (((segPtr->typePtr == &tkTextToggleOnType)
		|| (segPtr->typePtr == &tkTextToggleOffType))
		&& (segPtr->body.toggle.tagPtr == tagPtr)) {
	    toggleSegPtr = segPtr;
	}
    }
3360
3361
3362
3363
3364
3365
3366
3367

3368
3369
3370
3371
3372
3373
3374
3388
3389
3390
3391
3392
3393
3394

3395
3396
3397
3398
3399
3400
3401
3402







-
+







    /*
     * 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) {
    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;

3524
3525
3526
3527
3528
3529
3530
3531

3532
3533
3534
3535
3536
3537
3538
3552
3553
3554
3555
3556
3557
3558

3559
3560
3561
3562
3563
3564
3565
3566







-
+







    /*
     * 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) {
    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]++;
	    }
3861
3862
3863
3864
3865
3866
3867
3868

3869
3870
3871
3872
3873
3874
3875
3889
3890
3891
3892
3893
3894
3895

3896
3897
3898
3899
3900
3901
3902
3903







-
+







	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);
		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);
    }
}

4541
4542
4543
4544
4545
4546
4547
4548

4549
4550
4551
4552
4553
4554
4555
4569
4570
4571
4572
4573
4574
4575

4576
4577
4578
4579
4580
4581
4582
4583







-
+







 *
 *--------------------------------------------------------------
 */

static TkTextSegment *
CharSplitProc(
    TkTextSegment *segPtr,	/* Pointer to segment to split. */
    TkSizeT index)			/* Position within segment at which to
    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;
4661
4662
4663
4664
4665
4666
4667
4668

4669
4670
4671
4672
4673
4674
4675
4689
4690
4691
4692
4693
4694
4695

4696
4697
4698
4699
4700
4701
4702
4703







-
+







    /*
     * 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) {
    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') {
Changes to generic/tkTextDisp.c.
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181







-
+

















-
+







    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 tabStyle;		/* One of TK_TEXT_TABSTYLE_TABULAR or TK_TEXT_TABSTYLE_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
    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. */
    GC ulGC;			/* Graphics context for underline. */
    GC ovGC;			/* Graphics context for overstrike. */
    StyleValues *sValuePtr;	/* Raw information from which GCs were
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301







-
+







 *				neighboring lines (see DisplayLineBackground).
 * NEW_LAYOUT -			Non-zero means that the line has been
 *				re-layed out since the last time the display
 *				was updated.
 * TOP_LINE -			Non-zero means that this was the top line in
 *				in the window the last time that the window
 *				was laid out. This is important because a line
 *				may be displayed differently if its at the top
 *				may be displayed differently if it's at the top
 *				or bottom than if it's in the middle
 *				(e.g. beveled edges aren't displayed for
 *				middle lines if the adjacent line has a
 *				similar background).
 * BOTTOM_LINE -		Non-zero means that this was the bottom line
 *				in the window the last time that the window
 *				was laid out.
414
415
416
417
418
419
420
421

422
423
424
425
426
427
428
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
    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
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450







-
+







} TextDInfo;

/*
 * In TkTextDispChunk structures for character segments, the clientData field
 * points to one of the following structures:
 */

#if !defined(TK_LAYOUT_WITH_BASE_CHUNKS)
#ifndef 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;
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
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







+
-
+



















+
-
+
+







	    spacing3Prio = tagPtr->priority;
	}
	if ((tagPtr->tabStringPtr != NULL)
		&& (tagPtr->priority > tabPrio)) {
	    styleValues.tabArrayPtr = tagPtr->tabArrayPtr;
	    tabPrio = tagPtr->priority;
	}
	if (((tagPtr->tabStyle == TK_TEXT_TABSTYLE_TABULAR)
	if ((tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE)
		|| (tagPtr->tabStyle == TK_TEXT_TABSTYLE_WORDPROCESSOR))
		&& (tagPtr->priority > tabStylePrio)) {
	    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_CHAR)
	if ((tagPtr->wrapMode != TEXT_WRAPMODE_NULL)
		|| (tagPtr->wrapMode == TEXT_WRAPMODE_NONE)
		|| (tagPtr->wrapMode == TEXT_WRAPMODE_WORD))
		&& (tagPtr->priority > wrapPrio)) {
	    styleValues.wrapMode = tagPtr->wrapMode;
	    wrapPrio = tagPtr->priority;
	}
    }
    if (tagPtrs != NULL) {
	ckfree(tagPtrs);
1166
1167
1168
1169
1170
1171
1172
1173

1174
1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182


1183
1184
1185
1186
1187
1188
1189
1190







-
+






-
-
+







    TkTextDispChunk *tabChunkPtr;
				/* Pointer to the chunk containing the
				 * previous tab stop. */
    int maxBytes;		/* Maximum number of bytes to include in this
				 * chunk. */
    TkTextTabArray *tabArrayPtr;/* Tab stops for line; taken from style for
				 * the first character on line. */
    int tabStyle;		/* One of TABULAR or WORDPROCESSOR. */
    int tabStyle;		/* One of TK_TEXT_TABSTYLE_TABULAR or TK_TEXT_TABSTYLE_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;
    int byteOffset, ascent, descent, code, elide, elidesize;
    StyleValues *sValuePtr;
    TkTextElideInfo info;	/* Keep track of elide state. */

    /*
     * Create and initialize a new DLine structure.
     */

1214
1215
1216
1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228
1216
1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230







-
+







     * 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 (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
1337
1338
1339
1340
1341
1342
1343

1344
1345
1346
1347
1348
1349
1350
1351







-
+







     * 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)) {
    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.
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1391







-
+







	 * 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) {
	    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
2560
2561
2562
2563
2564
2565
2566







2567
2568
2569
2570
2571
2572
2573
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582







+
+
+
+
+
+
+







	    }
	    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 ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
	    /*
	     * A displayProc called in the loop above invoked a binding
	     * that caused the widget to be deleted. Don't do anything.
	     */
	    return;
	}
	if (dInfoPtr->dLinesInvalidated) {
	    return;
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
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
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







-
+








-
+

















-
+







	    dInfoPtr->lastMetricUpdateLine, 256);

    dInfoPtr->currentMetricUpdateLine = lineNum;

    if (tkTextDebug) {
	char buffer[2 * TCL_INTEGER_SPACE + 1];

	sprintf(buffer, "%d %d", lineNum, dInfoPtr->lastMetricUpdateLine);
	snprintf(buffer, sizeof(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
    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). 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_BackgroundError(textPtr->interp);
	    }
            Tcl_Release((ClientData) textPtr->interp);
            Tcl_DecrRefCount(textPtr->afterSyncCmd);
            textPtr->afterSyncCmd = NULL;
	}

        /*
3160
3161
3162
3163
3164
3165
3166
3167

3168
3169
3170
3171
3172
3173
3174
3169
3170
3171
3172
3173
3174
3175

3176
3177
3178
3179
3180
3181
3182
3183







-
+








    if (NewSyncState != OldSyncState) {
	if (NewSyncState) {
	    textPtr->dInfoPtr->flags &= ~OUT_OF_SYNC;
	} else {
	    textPtr->dInfoPtr->flags |= OUT_OF_SYNC;
	}
	Tk_SendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
	TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
		Tcl_NewBooleanObj(NewSyncState));
    }
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+
-













-
+







	    }

	    /*
	     * 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) {
	    if (textPtr->dInfoPtr->metricEpoch == -1 && lineNum == endLine) {


		/*
		 * We have looped over all lines, so we're done.
		 */

		break;
	    }
	}

	if (lineNum < totalLines) {
	    if (tkTextDebug) {
		char buffer[4 * TCL_INTEGER_SPACE + 3];

		sprintf(buffer, "%d %d %d %d",
		snprintf(buffer, sizeof(buffer), "%d %d %d %d",
			lineNum, endLine, totalLines, count);
		LOG("tk_textInvalidateLine", buffer);
	    }

	    /*
	     * Now update the line's metrics if necessary.
	     */
4129
4130
4131
4132
4133
4134
4135
4136

4137
4138
4139
4140
4141
4142
4143
4137
4138
4139
4140
4141
4142
4143

4144
4145
4146
4147
4148
4149
4150
4151







-
+







    if (tkTextDebug) {
	char buffer[2 * TCL_INTEGER_SPACE + 1];

	if (TkBTreeNextLine(textPtr, linePtr) == NULL) {
	    Tcl_Panic("Mustn't ever update line height of last artificial line");
	}

	sprintf(buffer, "%d %d", TkBTreeLinesTo(textPtr,linePtr), pixelHeight);
	snprintf(buffer, sizeof(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);
    }
4216
4217
4218
4219
4220
4221
4222
4223

4224
4225
4226
4227
4228
4229
4230
4224
4225
4226
4227
4228
4229
4230

4231
4232
4233
4234
4235
4236
4237
4238







-
+







    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,
     * handlers to be invoked, hence the refcount management 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++;
4495
4496
4497
4498
4499
4500
4501







4502
4503
4504
4505
4506

4507
4508
4509
4510
4511
4512
4513
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







+
+
+
+
+
+
+




-
+







		if (tkTextDebug) {
		    char string[TK_POS_CHARS];

		    TkTextPrintIndex(textPtr, &dlPtr->index, string);
		    LOG("tk_textRedraw", string);
		}
		DisplayDLine(textPtr, dlPtr, prevPtr, pixmap);
		if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
		    /*
		     * DisplayDLine called a displayProc which invoked a binding
		     * that caused the widget to be deleted. Don't do anything.
		     */
		    goto end;
		}
		if (dInfoPtr->dLinesInvalidated) {
#ifndef TK_NO_DOUBLE_BUFFERING
		    Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
		    return;
		    goto end;
		}
		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
4722
4723
4724
4725
4726
4727
4728






4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
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







+
+
+
+
+
+





-







    rect.x = x;
    rect.y = y;
    rect.width = width;
    rect.height = height;
    TkUnionRectWithRegion(&rect, damageRgn, damageRgn);

    TextInvalidateRegion(textPtr, damageRgn);

    TkDestroyRegion(damageRgn);

    /*
     * Schedule the redisplay operation if there isn't one already scheduled.
     */

    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	dInfoPtr->flags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayText, textPtr);
    }
    TkDestroyRegion(damageRgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TextInvalidateRegion --
 *
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4795
4796
4797
4798
4799
4800
4801




4802
4803
4804
4805
4806
4807
4808







-
-
-
-







	    dlPtr->flags |= OLD_Y_INVALID;
	}
    }
    if (dInfoPtr->topOfEof < maxY) {
	dInfoPtr->topOfEof = maxY;
    }

    /*
     * Schedule the redisplay operation if there isn't one already scheduled.
     */

    inset = textPtr->borderWidth + textPtr->highlightWidth;
    if ((rect.x < (inset + textPtr->padX))
	    || (rect.y < (inset + textPtr->padY))
	    || ((int) (rect.x + rect.width) > (Tk_Width(textPtr->tkwin)
		    - inset - textPtr->padX))
	    || (maxY > (Tk_Height(textPtr->tkwin) - inset - textPtr->padY))) {
	dInfoPtr->flags |= REDRAW_BORDERS;
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
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







-
+



















-
+







    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;
    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] == '-') {
	const char *switchStr =
		TkGetStringFromObj(objv[2], &switchLength);
		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;
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7571
7572
7573
7574
7575
7576
7577

7578
7579
7580
7581
7582
7583
7584







-







				 * 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.
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
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







-
+



-
+












-
+
-








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
    int 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
    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. */
    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;
    int nextX, bytesThatFit, count;
    TkSizeT bytesThatFit;
    CharInfo *ciPtr;
    char *p;
    TkTextSegment *nextPtr;
    Tk_FontMetrics fm;
#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
    const char *line;
    int lineOffset;
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
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







-
+






-
-
+
+




















-
+








    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));
	bciPtr = (BaseCharInfo *)ckalloc(sizeof(BaseCharInfo));
	baseString = &bciPtr->baseChars;
	Tcl_DStringInit(baseString);
	bciPtr->width = 0;

	ciPtr = &bciPtr->ci;
    } else {
	bciPtr = baseCharChunkPtr->clientData;
	ciPtr = ckalloc(sizeof(CharInfo));
	bciPtr = (BaseCharInfo *)baseCharChunkPtr->clientData;
	ciPtr = (CharInfo *)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 < 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,
7763
7764
7765
7766
7767
7768
7769
7770
7771


7772
7773
7774
7775
7776
7777
7778
7777
7778
7779
7780
7781
7782
7783


7784
7785
7786
7787
7788
7789
7790
7791
7792







-
-
+
+







    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);
#ifndef TK_LAYOUT_WITH_BASE_CHUNKS
    ciPtr = (CharInfo *)ckalloc((Tk_Offset(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--;
7879
7880
7881
7882
7883
7884
7885
7886

7887
7888
7889
7890
7891
7892
7893
7893
7894
7895
7896
7897
7898
7899

7900
7901
7902
7903
7904
7905
7906
7907







-
+







    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)
#ifndef TK_LAYOUT_WITH_BASE_CHUNKS
    if (chars == NULL) {
	chars = ciPtr->chars;
	charsLen = ciPtr->numBytes;
    }
    if (end == -1) {
	end = charsLen;
    }
7984
7985
7986
7987
7988
7989
7990
7991

7992
7993
7994
7995
7996
7997
7998
7998
7999
8000
8001
8002
8003
8004

8005
8006
8007
8008
8009
8010
8011
8012







-
+







	 * The chunk is off-screen.
	 */

	return;
    }

#ifdef TK_DRAW_IN_CONTEXT
    bciPtr = ciPtr->baseChunkPtr->clientData;
    bciPtr = (BaseCharInfo *)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.
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
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







-
+


-
+


-


















-
+








-
-
+
+

-
-
-
-
-
+


-
-
+
+

-
-
-
-
+

-
-
+
+

-
-
-
-
+
+
+
+
-
-
+
-
-







    static const char *const subcommands[] = {
	"moveto", "scroll", NULL
    };
    enum viewSubcmds {
	VIEW_MOVETO, VIEW_SCROLL
    };
    static const char *const units[] = {
	"pages", "pixels", "units", NULL
	"units", "pages", "pixels", NULL
    };
    enum viewUnits {
	VIEW_SCROLL_PAGES, VIEW_SCROLL_PIXELS, VIEW_SCROLL_UNITS
	VIEW_SCROLL_UNITS, VIEW_SCROLL_PAGES, VIEW_SCROLL_PIXELS
    };
    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");
	    Tcl_WrongNumArgs(interp, 3, objv, "number units|pages|pixels");
	    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;
	    if (Tcl_GetIntFromObj(interp, objv[3], intPtr) == TCL_OK) {
		return TKTEXT_SCROLL_PAGES;
	    }
	    *intPtr = (d > 0) ? ceil(d) : floor(d);
	    if (dblPtr) {
		*dblPtr = d;
	    }
	    return TKTEXT_SCROLL_PAGES;
	    break;
	case VIEW_SCROLL_PIXELS:
	    if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[3],
		    intPtr) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
		    intPtr) == TCL_OK) {
		return TKTEXT_SCROLL_PIXELS;
	    }
	    if (dblPtr) {
		*dblPtr = (double)*intPtr;
	    }
	    return TKTEXT_SCROLL_PIXELS;
	    break;
	case VIEW_SCROLL_UNITS:
	    if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
		return TKTEXT_SCROLL_ERROR;
	    if (Tcl_GetIntFromObj(interp, objv[3], intPtr) == TCL_OK) {
		return TKTEXT_SCROLL_UNITS;
	    }
	    *intPtr = (d > 0) ? ceil(d) : floor(d);
	    if (dblPtr) {
		*dblPtr = d;
	    }
	    break;
	default:
	    Tcl_Panic("unexpected switch fallthrough");
	}
	    return TKTEXT_SCROLL_UNITS;
	}
    }
    }
    Tcl_Panic("unexpected switch fallthrough");
    return TKTEXT_SCROLL_ERROR;
}

#ifdef TK_LAYOUT_WITH_BASE_CHUNKS
/*
 *----------------------------------------------------------------------
 *
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
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







-
+
















-
+







#ifdef TK_DRAW_IN_CONTEXT
	chunkPtr->x += widthAdjust;
#endif /* TK_DRAW_IN_CONTEXT */

	if (chunkPtr->displayProc != CharDisplayProc) {
	    continue;
	}
	ciPtr = chunkPtr->clientData;
	ciPtr = (CharInfo *)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 = (CharInfo *)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 */
8963
8964
8965
8966
8967
8968
8969
8970

8971
8972
8973
8974
8975
8976
8977
8966
8967
8968
8969
8970
8971
8972

8973
8974
8975
8976
8977
8978
8979
8980







-
+







	baseCharChunkPtr = NULL;
    }

    for (chunkPtr=baseChunkPtr; chunkPtr!=NULL; chunkPtr=chunkPtr->nextPtr) {
	if (chunkPtr->undisplayProc != CharUndisplayProc) {
	    continue;
	}
	ciPtr = chunkPtr->clientData;
	ciPtr = (CharInfo *)chunkPtr->clientData;
	if (ciPtr->baseChunkPtr != baseChunkPtr) {
	    break;
	}

	ciPtr->baseChunkPtr = NULL;
	ciPtr->chars = NULL;
    }
9013
9014
9015
9016
9017
9018
9019
9020

9021
9022
9023
9024
9025
9026
9027
9016
9017
9018
9019
9020
9021
9022

9023
9024
9025
9026
9027
9028
9029
9030







-
+







    StyleValues *sv1;
    StyleValues *sv2;

    if (style1 == style2) {
	return 1;
    }

#if !defined(TK_DRAW_IN_CONTEXT)
#ifndef TK_DRAW_IN_CONTEXT
    if (
#ifdef MAC_OSX_TK
	    !TkMacOSXCompareColors(style1->fgGC->foreground,
		    style2->fgGC->foreground)
#else
	    style1->fgGC->foreground != style2->fgGC->foreground
#endif
9083
9084
9085
9086
9087
9088
9089
9090

9091
9092
9093
9094
9095
9096
9097

9098
9099
9100
9101
9102
9103
9104
9086
9087
9088
9089
9090
9091
9092

9093
9094
9095
9096
9097
9098
9099

9100
9101
9102
9103
9104
9105
9106
9107







-
+






-
+







	return;
    }

    /*
     * Reinstitute this base chunk for re-layout.
     */

    ciPtr = chunkPtr->clientData;
    ciPtr = (CharInfo *)chunkPtr->clientData;
    baseCharChunkPtr = ciPtr->baseChunkPtr;

    /*
     * Remove the chunk data from the base chunk data.
     */

    bciPtr = baseCharChunkPtr->clientData;
    bciPtr = (BaseCharInfo *)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");
    }
Changes to generic/tkTextImage.c.
9
10
11
12
13
14
15




16
17
18
19
20
21

22
23
24
25
26
27
28
9
10
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 "tkPort.h"
#include "tkText.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Macro that determines the size of an embedded image segment:
 */

#define EI_SEG_SIZE \
	(offsetof(TkTextSegment, body) + sizeof(TkTextEmbImage))
	((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
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57







-
+







			    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 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);

/*
79
80
81
82
83
84
85
86

87
88
89

90
91

92
93

94
95
96

97
98
99
100
101
102
103
83
84
85
86
87
88
89

90
91
92

93
94

95
96

97
98
99

100
101
102
103
104
105
106
107







-
+


-
+

-
+

-
+


-
+








/*
 * 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),
	"center", -1, Tk_Offset(TkTextEmbImage, align),
	0, alignStrings, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padX), 0, 0, 0},
	"0", -1, Tk_Offset(TkTextEmbImage, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbImage, padY), 0, 0, 0},
	"0", -1, Tk_Offset(TkTextEmbImage, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageString),
	NULL, -1, Tk_Offset(TkTextEmbImage, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-name", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbImage, imageName),
	NULL, -1, Tk_Offset(TkTextEmbImage, imageName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175







-
+







	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,
	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;
	}
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202







-
+







		    "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,
		    (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;
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290





291
292

293
294
295
296
297
298


299
300
301
302
303
304
305
279
280
281
282
283
284
285

286








287
288
289
290
291


292



293
294
295
296
297
298
299
300
301
302
303
304







-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
-
-
-



+
+







	return TCL_OK;
    }
    case CMD_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	Tcl_Obj *resultObj;

	if (objc != 3) {
	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),
	    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));
		    -1));
	}
	    }
	if (resultObj == NULL) {
	    return TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	    return TCL_OK;
	}
	Tcl_WrongNumArgs(interp, 3, objv, NULL);
	break;
    }
    default:
	Tcl_Panic("unexpected switch fallthrough");
    }
    return TCL_ERROR;
}

330
331
332
333
334
335
336
337
338
339

340
341
342
343
344

345
346
347
348
349
350
351
329
330
331
332
333
334
335

336

337



338

339
340
341
342
343
344
345
346







-

-
+
-
-
-

-
+







    int objc,			/* Number of strings in objv. */
    Tcl_Obj *const objv[])	/* Array of strings describing configuration
				 * options. */
{
    Tk_Image image;
    Tcl_DString newName;
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char *name;
    int dummy;
    int dummy, length;
    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,
    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
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

415
416
417
418




419

420

421

422
423
424
425
426
427



428
429
430
431
432
433
434
380
381
382
383
384
385
386
387





388













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 (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) {
		count = newVal;
	    }
	    if (len == strlen(haveName)) {
	    	conflict = 1;
	    }
	}
    }

    Tcl_DStringInit(&newName);
    Tcl_DStringAppend(&newName, name, -1);

    while (Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name)) {
    if (conflict) {
    	char buf[4 + TCL_INTEGER_SPACE];

	sprintf(buf, "#%d", count+1);
	char buf[4 + TCL_INTEGER_SPACE];
	snprintf(buf, sizeof(buf), "#%d", ++textPtr->sharedTextPtr->imageCount);
	Tcl_DStringSetLength(&newName, 0);
	Tcl_DStringAppend(&newName, name, -1);
	Tcl_DStringAppend(&newName, buf, -1);
	name = Tcl_DStringValue(&newName);
    }
    length = strlen(name);
    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);
    eiPtr->body.ei.name = (char *)ckalloc(length + 1);
    memcpy(eiPtr->body.ei.name, name, length + 1);
    Tcl_SetObjResult(textPtr->interp, Tcl_NewStringObj(name, -1));
    Tcl_DStringFree(&newName);

    return TCL_OK;
}

/*
 *--------------------------------------------------------------
531
532
533
534
535
536
537
538

539
540
541
542

543
544
545
546
547
548
549
509
510
511
512
513
514
515

516
517
518
519

520
521
522
523
524
525
526
527







-
+



-
+







 */

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
    int 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
    TCL_UNUSED(int),		/* 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)
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616







-
+







    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);
		eiPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageDisplayProc --
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
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







-
-
-
+
+
+

















-
+




-
+





+
+
+
+
+
+
+
+
+
+
+
-
+







 *
 * TkTextImageIndex --
 *
 *	Given the name of an embedded image within a text widget, returns an
 *	index corresponding to the image's position in the text.
 *
 * Results:
 *	The return value is 1 if there is an embedded image by the given name
 *	in the text widget, 0 otherwise. If the image exists, *indexPtr is
 *	filled in with its index.
 *	The return value is TCL_OK if there is an embedded image by the given
 *	name in the text widget, TCL_ERROR otherwise. If the image exists,
 *	*indexPtr is filled in with its index.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextImageIndex(
    TkText *textPtr,		/* Text widget containing image. */
    const char *name,		/* Name of image. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *eiPtr;

    if (textPtr == NULL) {
	return 0;
	return TCL_ERROR;
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name);
    if (hPtr == NULL) {
	return 0;
	return TCL_ERROR;
    }
    eiPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->linePtr = eiPtr->body.ei.linePtr;
    indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr);

    /*
     * If indexPtr refers to somewhere outside the -startline/-endline
     * range limits of the widget, error out since the image indeed is not
     * reachable from this text widget (it may be reachable from a peer).
     */

    if (TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 1) == TCL_ERROR) {
	return TCL_ERROR;
    }

    return 1;
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EmbImageProc --
 *
Changes to generic/tkTextIndex.c.
11
12
13
14
15
16
17




18
19
20
21
22
23
24
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28







+
+
+
+







 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkText.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Index to use to select last character in line (very large integer):
 */

#define LAST_CHAR 1000000

/*
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+







#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))
	((objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(epoch))

/*
 * Define the 'textindex' object type, which Tk uses to represent indices in
 * text widgets internally.
 */

const Tcl_ObjType tkTextIndexType = {
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118







-
+







}

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;
    int epoch;
    TkTextIndex *dupIndexPtr, *indexPtr;

    dupIndexPtr = (TkTextIndex *)ckalloc(sizeof(TkTextIndex));
    indexPtr = GET_TEXTINDEX(srcPtr);
    epoch = GET_INDEXEPOCH(srcPtr);

    dupIndexPtr->tree = indexPtr->tree;
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220







-
+







				 * position. */
{
    TkTextIndex index;
    TkTextIndex *indexPtr = NULL;
    int cache;

    if (objPtr->typePtr == &tkTextIndexType) {
	TkSizeT epoch;
	int epoch;

	indexPtr = GET_TEXTINDEX(objPtr);
	epoch = GET_INDEXEPOCH(objPtr);

	if (epoch == textPtr->sharedTextPtr->stateEpoch) {
	    if (indexPtr->textPtr == textPtr) {
		return indexPtr;
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439







-
+







	     * 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) {
	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 the index
		 * falls in the middle of a UTF-8 character, it will be
		 * adjusted to the end of that UTF-8 character.
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494







-
+







				 * 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;
    Tcl_UniChar ch = 0;

    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
527
528
529
530
531
532
533

534
535
536
537

538
539
540
541
542
543
544
545







-
+



-
+







	    end = start + segPtr->size;
	    for (p = start; p < end; p += offset) {
		if (charIndex == 0) {
		    indexPtr->byteIndex = index;
		    return indexPtr;
		}
		charIndex--;
		offset = TkUtfToUniChar(p, &ch);
		offset = Tcl_UtfToUniChar(p, &ch);
		index += offset;
	    }
	} else {
	    if (charIndex < (int)segPtr->size) {
	    if (charIndex < segPtr->size) {
		indexPtr->byteIndex = index;
		break;
	    }
	    charIndex -= segPtr->size;
	    index += segPtr->size;
	}
    }
561
562
563
564
565
566
567
568

569
570
571
572

573
574
575
576
577
578
579
565
566
567
568
569
570
571

572
573
574
575

576
577
578
579
580
581
582
583







-
+



-
+







 *
 *---------------------------------------------------------------------------
 */

TkTextSegment *
TkTextIndexToSeg(
    const TkTextIndex *indexPtr,/* Text index. */
    TkSizeT *offsetPtr)		/* Where to store offset within segment, or
    int *offsetPtr)		/* Where to store offset within segment, or
				 * NULL if offset isn't wanted. */
{
    TkTextSegment *segPtr;
    TkSizeT offset;
    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) {
757
758
759
760
761
762
763
764

765
766
767
768

769
770
771
772
773
774
775
761
762
763
764
765
766
767

768
769
770
771

772
773
774
775
776
777
778
779







-
+



-
+







     *---------------------------------------------------------------------
     */

    if (TkTextMarkNameToIndex(textPtr, string, indexPtr) == TCL_OK) {
	goto done;
    }

    if (TkTextWindowIndex(textPtr, string, indexPtr) != 0) {
    if (TkTextWindowIndex(textPtr, string, indexPtr) == TCL_OK) {
	goto done;
    }

    if (TkTextImageIndex(textPtr, string, indexPtr) != 0) {
    if (TkTextImageIndex(textPtr, string, indexPtr) == TCL_OK) {
	goto done;
    }

    /*
     *------------------------------------------------
     * Stage 2: start again by parsing the base index.
     *------------------------------------------------
913
914
915
916
917
918
919
920

921
922
923
924
925
926
927
917
918
919
920
921
922
923

924
925
926
927
928
929
930
931







-
+







	 * See if the base position is the name of an embedded window.
	 */

	c = *endOfBase;
	*endOfBase = 0;
	result = TkTextWindowIndex(textPtr, Tcl_DStringValue(&copy), indexPtr);
	*endOfBase = c;
	if (result != 0) {
	if (result == TCL_OK) {
	    goto gotBase;
	}
    }
    if ((string[0] == 'e')
	    && (strncmp(string, "end",
	    endOfBase-Tcl_DStringValue(&copy)) == 0)) {
	/*
950
951
952
953
954
955
956
957

958
959
960
961
962
963
964
954
955
956
957
958
959
960

961
962
963
964
965
966
967
968







-
+







	 * See if the base position is the name of an embedded image.
	 */

	c = *endOfBase;
	*endOfBase = 0;
	result = TkTextImageIndex(textPtr, Tcl_DStringValue(&copy), indexPtr);
	*endOfBase = c;
	if (result != 0) {
	if (result == TCL_OK) {
	    goto gotBase;
	}
    }
    goto error;

    /*
     *-------------------------------------------------------------------
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
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







+








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



















-
+







  done:
    if (canCachePtr != NULL) {
	*canCachePtr = canCache;
    }
    if (indexPtr->linePtr == NULL) {
	Tcl_Panic("Bad index created");
    }
    TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 0);
    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;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexAdjustToStartEnd --
 *
 *      Adjust indexPtr to the -startline/-endline range, or just check
 *      if indexPtr is out of this range.
 *
 * Results:
 *	The return value is a standard Tcl return result. If check is true,
 *      return TCL_ERROR if indexPtr is outside the -startline/-endline
 *      range (indexPtr is not modified).
 *      If check is false, adjust indexPtr to -startline/-endline.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

int
TkTextIndexAdjustToStartEnd(
    TkText *textPtr,
    TkTextIndex *indexPtr,  /* Pointer to index. */
    int check)		    /* 1 means only check indexPtr against
			     * the -startline/-endline range
			     * 0 means adjust to this range */
{
    int bound;
    TkTextIndex indexBound;

    if (!textPtr) {
	return TCL_OK;
    }
    if (textPtr->start != NULL) {
	bound = TkBTreeLinesTo(NULL, textPtr->start);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0,
		&indexBound);
	if (TkTextIndexCmp(indexPtr, &indexBound) < 0) {
	    if (check) {
		return TCL_ERROR;
	    }
	    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0,
		    indexPtr);
	}
    }
    if (textPtr->end != NULL) {
	bound = TkBTreeLinesTo(NULL, textPtr->end);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0,
		&indexBound);
	if (TkTextIndexCmp(indexPtr, &indexBound) > 0) {
	    if (check) {
		return TCL_ERROR;
	    }
	    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0,
		    indexPtr);
	}
    }
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextPrintIndex --
 *
 *	This function generates a string description of an index, suitable for
 *	reading in again later.
 *
 * Results:
 *	The characters pointed to by string are modified. Returns the number
 *	of characters in the string.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

TkSizeT
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;
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
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







-
+
















-
+







	     * 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) {
	if (numBytes <= segPtr->size) {
	    break;
	}
	if (segPtr->typePtr == &tkTextCharType) {
	    charIndex += Tcl_NumUtfChars(segPtr->body.chars, segPtr->size);
	} else {
	    charIndex += segPtr->size;
	}
	numBytes -= segPtr->size;
    }

    if (segPtr->typePtr == &tkTextCharType) {
	charIndex += Tcl_NumUtfChars(segPtr->body.chars, numBytes);
    } else {
	charIndex += numBytes;
    }

    return sprintf(string, "%d.%d",
    return snprintf(string, TK_POS_CHARS, "%d.%d",
	    TkBTreeLinesTo(textPtr, indexPtr->linePtr) + 1, charIndex);
}

/*
 *---------------------------------------------------------------------------
 *
 * TkTextIndexCmp --
1484
1485
1486
1487
1488
1489
1490
1491

1492
1493
1494
1495
1496
1497
1498
1550
1551
1552
1553
1554
1555
1556

1557
1558
1559
1560
1561
1562
1563
1564







-
+







				 * 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;
    int byteOffset;
    char *start, *end, *p;
    int ch;
    int elide = 0;
    int checkElided = (type & COUNT_DISPLAY);

    if (charCount < 0) {
	TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type);
1672
1673
1674
1675
1676
1677
1678
1679

1680
1681
1682
1683
1684
1685
1686
1738
1739
1740
1741
1742
1743
1744

1745
1746
1747
1748
1749
1750
1751
1752







-
+







    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;
    int byteCount, offset;
    TkTextSegment *segPtr, *segPtr1;
    TkTextLine *linePtr;

    if (indexPtr1->linePtr == indexPtr2->linePtr) {
        return indexPtr2->byteIndex - indexPtr1->byteIndex;
    }

1749
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
1764
1815
1816
1817
1818
1819
1820
1821

1822

1823
1824
1825
1826
1827
1828
1829







-
+
-







				/* 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 byteOffset, maxBytes, count = 0, elide = 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.
     */

1840
1841
1842
1843
1844
1845
1846
1847

1848
1849
1850

1851
1852
1853
1854
1855
1856
1857
1905
1906
1907
1908
1909
1910
1911

1912
1913
1914

1915
1916
1917
1918
1919
1920
1921
1922







-
+


-
+







		    }
		    byteOffset = 0;
		    continue;
		}
	    }

	    if (segPtr->typePtr == &tkTextCharType) {
		TkSizeT byteLen = segPtr->size - byteOffset;
		int byteLen = segPtr->size - byteOffset;
		unsigned char *str = (unsigned char *)
			segPtr->body.chars + byteOffset;
		TkSizeT i;
		int i;

		if (segPtr == seg2Ptr) {
		    if (byteLen + byteOffset > maxBytes) {
			byteLen = maxBytes - byteOffset;
		    }
		}
		i = byteLen;
1873
1874
1875
1876
1877
1878
1879
1880

1881
1882
1883
1884
1885
1886
1887
1938
1939
1940
1941
1942
1943
1944

1945
1946
1947
1948
1949
1950
1951
1952







-
+







		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;
		    int byteLen = segPtr->size - byteOffset;

		    if (segPtr == seg2Ptr) {
			if (byteLen + byteOffset > maxBytes) {
			    byteLen = maxBytes - byteOffset;
			}
		    }
		    count += byteLen;
2052
2053
2054
2055
2056
2057
2058
2059

2060
2061
2062
2063
2064
2065
2066
2117
2118
2119
2120
2121
2122
2123

2124
2125
2126
2127
2128
2129
2130
2131







-
+







		 * 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) {
	    if (segSize <= segPtr->size) {
		break;
	    }
	    segSize -= segPtr->size;
	}
    }

    /*
2293
2294
2295
2296
2297
2298
2299
2300

2301
2302
2303
2304
2305
2306
2307
2358
2359
2360
2361
2362
2363
2364

2365
2366
2367
2368
2369
2370
2371
2372







-
+







	    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;
	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.
	 */

2336
2337
2338
2339
2340
2341
2342
2343

2344
2345
2346
2347
2348
2349
2350
2401
2402
2403
2404
2405
2406
2407

2408
2409
2410
2411
2412
2413
2414
2415







-
+







		TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr,
			COUNT_INDICES);
	    }
	}
    } else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0)
	    && (length >= 5)) {
	int firstChar = 1;
	TkSizeT offset;
	int offset;

	if (modifier == TKINDEX_DISPLAY) {
	    TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr,
		    COUNT_DISPLAY_INDICES);
	}

	/*
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
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







-
+







+
+
+











-
+
-
-
-







	    if (segPtr->typePtr == &tkTextCharType) {

		int ch;
		TkUtfToUniChar(segPtr->body.chars + offset, &ch);
		if (!Tcl_UniCharIsWordChar(ch)) {
		    break;
		}
		if (offset + 1 > 1) {
		if (offset > 0) {
		    chSize = (segPtr->body.chars + offset
			    - TkUtfPrev(segPtr->body.chars + offset,
			    segPtr->body.chars));
		}
		firstChar = 0;
	    }
            if (offset == 0) {
		if (indexPtr->byteIndex == 0) {
		    goto done;
		}
                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 (offset < 0) {
		if (indexPtr->byteIndex == 0) {
		    goto done;
		}
		segPtr = TkTextIndexToSeg(indexPtr, &offset);
	    }
	}

	if (!firstChar) {
	    if (modifier == TKINDEX_DISPLAY) {
		TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr,
Changes to generic/tkTextMark.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
15
16
17
18
19
20
21


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38


39
40
41
42
43
44
45
46
47







-
-
+
+















-
-
+
+







#include "tkText.h"
#include "tk3d.h"

/*
 * Macro that determines the size of a mark segment:
 */

#define MSEG_SIZE (offsetof(TkTextSegment, body) \
	+ sizeof(TkTextMark))
#define MSEG_SIZE ((unsigned)(Tk_Offset(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,
			    TkTextSegment *segPtr, int offset, int maxX,
			    int 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);


122
123
124
125
126
127
128
129

130
131
132
133
134
135
136

137
138
139
140
141
142
143
122
123
124
125
126
127
128

129
130
131
132
133
134
135

136
137
138
139
140
141
142
143







-
+






-
+







	    sizeof(char *), "mark option", 0, &optionIndex) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum markOptions) optionIndex) {
    case MARK_GRAVITY: {
	char c;
	TkSizeT length;
	int length;
	const char *str;

	if (objc < 4 || objc > 5) {
	    Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?");
	    return TCL_ERROR;
	}
	str = TkGetStringFromObj(objv[3], &length);
	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) {
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+







		typeStr = "right";
	    } else {
		typeStr = "left";
	    }
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1));
	    return TCL_OK;
	}
	str = TkGetStringFromObj(objv[4],&length);
	str = Tcl_GetStringFromObj(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 {
407
408
409
410
411
412
413
414

415
416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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
407
408
409
410
411
412
413

414
415
416

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436


437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463








464
465
466
467








468
469
470
471
472
473
474







-
+


-
+



















-
-




















+
-
+





-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-







 * TkTextMarkNameToIndex --
 *
 *	Given the name of a mark, return an index corresponding to the mark
 *	name.
 *
 * Results:
 *	The return value is TCL_OK if "name" exists as a mark in the text
 *	widget and is located within its -starline/-endline range. In this
 *	widget and is located within its -startline/-endline range. In this
 *	case *indexPtr is filled in with the next segment who is after the
 *	mark whose size is non-zero. TCL_ERROR is returned if the mark
 *	doesn't exist in the text widget, or if it is out of its -starline/
 *	doesn't exist in the text widget, or if it is out of its -startline/
 *	-endline range. In this latter case *indexPtr still contains valid
 *	information, in particular TkTextMarkNameToIndex called with the
 *	"insert" or "current" mark name may return TCL_ERROR, but *indexPtr
 *	contains the correct index of this mark before -startline or after
 *	-endline.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextMarkNameToIndex(
    TkText *textPtr,		/* Text widget containing mark. */
    const char *name,		/* Name of mark. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    TkTextSegment *segPtr;
    TkTextIndex index;
    int start, end;

    if (textPtr == NULL) {
        return TCL_ERROR;
    }

    if (!strcmp(name, "insert")) {
	segPtr = textPtr->insertMarkPtr;
    } else if (!strcmp(name, "current")) {
	segPtr = textPtr->currentMarkPtr;
    } else {
	Tcl_HashEntry *hPtr =
		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
     * If indexPtr refers to somewhere outside the -startline/-endline
     * range limits of the widget, error out since the mark indeed is not
     * reachable from this text widget (it may be reachable from a peer)
     * (bug 1630271).
     */

    if (textPtr->start != NULL) {
	start = TkBTreeLinesTo(NULL, textPtr->start);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0,
		&index);
	if (TkTextIndexCmp(indexPtr, &index) < 0) {
	    return TCL_ERROR;
	}
    }
    if (TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 1) == TCL_ERROR) {
	return TCL_ERROR;
    }

    if (textPtr->end != NULL) {
	end = TkBTreeLinesTo(NULL, textPtr->end);
	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0,
		&index);
	if (TkTextIndexCmp(indexPtr, &index) > 0) {
	    return TCL_ERROR;
	}
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MarkDeleteProc --
556
557
558
559
560
561
562
563

564
565
566
567

568
569
570
571
572
573
574
543
544
545
546
547
548
549

550
551
552
553

554
555
556
557
558
559
560
561







-
+



-
+







 */

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
    TCL_UNUSED(int),			/* 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
    TCL_UNUSED(int),		/* 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
Changes to generic/tkTextTag.c.
33
34
35
36
37
38
39
40




































































































































































































41
42
43

44
45

46
47
48
49
50
51





52
53

54
55

56
57
58
59
60
61
62
63







64
65
66
67
68
69
70






71
72
73
74
75
76
77






78
79

80
81

82
83
84
85
86
87
88
89







90
91

92
93

94
95
96
97



98
99
100


101
102
103


104
105
106
107
108
109
110
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

239
240

241
242





243
244
245
246
247
248

249
250

251
252







253
254
255
256
257
258
259
260






261
262
263
264
265
266
267






268
269
270
271
272
273
274

275
276

277
278







279
280
281
282
283
284
285
286

287
288

289
290



291
292
293
294


295
296
297


298
299
300
301
302
303
304
305
306








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
+

-
+

-
-
-
-
-
+
+
+
+
+

-
+

-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
+

-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
+

-
+

-
-
-
+
+
+

-
-
+
+

-
-
+
+







 * 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
};

/* This struct can be used for booleans, relief and pixels */
typedef struct {
	char *string;
	int value;
} IntStruct;

typedef struct {
	char *string;
	Tk_Justify value;
} JustifyStruct;

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);
}

#define OPTION_NONNEG		(1 << 10)

static int
SetPixels(void *clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tcl_Obj **value,
    char *recordPtr,
    int internalOffset,
    char *oldInternalPtr,
    int flags)
{
    IntStruct pixel = {NULL, INT_MIN};
    IntStruct *internalPtr = (IntStruct *)(recordPtr + internalOffset);

    if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) {
	if (Tk_GetPixelsFromObj(interp, tkwin, *value, &pixel.value) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((flags & OPTION_NONNEG) && pixel.value < 0) {
	    pixel.value = 0;
	}
	pixel.string = ckalloc((*value)->length + 1);
	strcpy(pixel.string, (*value)->bytes);
    }

    *((char **)oldInternalPtr) = NULL;
    *internalPtr = pixel;
    return TCL_OK;
};

static int
SetBoolean(void *clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tcl_Obj **value,
    char *recordPtr,
    int internalOffset,
    char *oldInternalPtr,
    int flags)
{
    IntStruct booleanVal = {NULL, -1};
    IntStruct *internalPtr = (IntStruct *)(recordPtr + internalOffset);

    if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) {
	if (Tcl_GetBooleanFromObj(interp, *value, &booleanVal.value) != TCL_OK) {
	    return TCL_ERROR;
	}
	booleanVal.string = ckalloc((*value)->length + 1);
	strcpy(booleanVal.string, (*value)->bytes);
    }

    *((char **)oldInternalPtr) = NULL;
    *internalPtr = booleanVal;
    return TCL_OK;
};

static int
SetRelief(void *clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tcl_Obj **value,
    char *recordPtr,
    int internalOffset,
    char *oldInternalPtr,
    int flags)
{
    IntStruct relief = {NULL, TK_RELIEF_NULL};
    IntStruct *internalPtr = (IntStruct *)(recordPtr + internalOffset);

    if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) {
	if (Tk_GetReliefFromObj(interp, *value, &relief.value) != TCL_OK) {
	    return TCL_ERROR;
	}
	relief.string = ckalloc((*value)->length + 1);
	strcpy(relief.string, (*value)->bytes);
    }

    *((char **)oldInternalPtr) = NULL;
    *internalPtr = relief;
    return TCL_OK;
};

static int
SetJustify(void *clientData,
    Tcl_Interp *interp,
    Tk_Window tkwin,
    Tcl_Obj **value,
    char *recordPtr,
    int internalOffset,
    char *oldInternalPtr,
    int flags)
{
    JustifyStruct justify = {NULL, (Tk_Justify)-1};
    JustifyStruct *internalPtr = (JustifyStruct *)(recordPtr + internalOffset);

    if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) {
	if (Tk_GetJustifyFromObj(interp, *value, &justify.value) != TCL_OK) {
	    return TCL_ERROR;
	}
	justify.string = ckalloc((*value)->length + 1);
	strcpy(justify.string, (*value)->bytes);
    }

    *((char **)oldInternalPtr) = NULL;
    *internalPtr = justify;
    return TCL_OK;
};

static Tcl_Obj *GetStruct(
    void *clientData,
    Tk_Window tkwin,
    char *recordPtr,
    int internalOffset)
{
    char **structPtr = (char **)(recordPtr + internalOffset);

    if (*structPtr == NULL || **structPtr == '\0') {
	return Tcl_NewObj();
    }
    return Tcl_NewStringObj(*structPtr, -1);
};


static void
FreeStruct(void *clientData,
    Tk_Window tkwin,
    char *internalPtr)
{
    char **structPtr = (char **)internalPtr;
    if (*structPtr) {
	ckfree(*structPtr);
	*structPtr = NULL;
    }
};

static const Tk_ObjCustomOption pixelsOption = {
    "pixels",			/* name */
    SetPixels,		/* setProc */
    GetStruct,		/* getProc */
    NULL,		/* restoreProc */
    FreeStruct,			/* freeProc */
    0
};

static const Tk_ObjCustomOption booleanOption = {
    "boolean",			/* name */
    SetBoolean,		/* setProc */
    GetStruct,		/* getProc */
    NULL,		/* restoreProc */
    FreeStruct,			/* freeProc */
    0
};

static const Tk_ObjCustomOption justifyOption = {
    "justify",			/* name */
    SetJustify,		/* setProc */
    GetStruct,		/* getProc */
    NULL,		/* restoreProc */
    FreeStruct,			/* freeProc */
    0
};

static const Tk_ObjCustomOption reliefOption = {
    "relief",			/* name */
    SetRelief,		/* setProc */
    GetStruct,		/* getProc */
    NULL,		/* restoreProc */
    FreeStruct,			/* freeProc */
    0
};

static const Tk_OptionSpec tagOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(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},
	NULL, -1, Tk_Offset(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},
	NULL, Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CUSTOM, "-elide", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, elideString),
	TK_OPTION_NULL_OK, &booleanOption, 0},
    {TK_OPTION_BITMAP, "-fgstipple", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(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},
	NULL, -1, Tk_Offset(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},
	NULL, -1, Tk_Offset(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CUSTOM, "-justify", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, justifyString), TK_OPTION_NULL_OK, &justifyOption, 0},
    {TK_OPTION_CUSTOM, "-lmargin1", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK, &pixelsOption, 0},
    {TK_OPTION_CUSTOM, "-lmargin2", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK, &pixelsOption, 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},
	NULL, -1, Tk_Offset(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CUSTOM, "-offset", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, &pixelsOption, 0},
    {TK_OPTION_CUSTOM, "-overstrike", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, overstrikeString),
	TK_OPTION_NULL_OK, &booleanOption, 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},
	NULL, -1, Tk_Offset(TkTextTag, overstrikeColor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CUSTOM, "-relief", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, &reliefOption, 0},
    {TK_OPTION_CUSTOM, "-rmargin", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, &pixelsOption, 0},
    {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(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},
	NULL, -1, Tk_Offset(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},
	NULL, -1, Tk_Offset(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CUSTOM, "-spacing1", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK|OPTION_NONNEG, &pixelsOption, 0},
    {TK_OPTION_CUSTOM, "-spacing2", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, spacing2String), TK_OPTION_NULL_OK|OPTION_NONNEG, &pixelsOption, 0},
    {TK_OPTION_CUSTOM, "-spacing3", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK|OPTION_NONNEG, &pixelsOption, 0},
    {TK_OPTION_STRING, "-tabs", NULL, NULL,
	NULL, offsetof(TkTextTag, tabStringPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0},
	NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-tabstyle", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, tabStyle),
	NULL, -1, Tk_Offset(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_CUSTOM, "-underline", NULL, NULL,
	NULL, -1, Tk_Offset(TkTextTag, underlineString),
	TK_OPTION_NULL_OK, &booleanOption, 0},
    {TK_OPTION_COLOR, "-underlinefg", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextTag, underlineColor),
        TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(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},
	NULL, -1, Tk_Offset(TkTextTag, wrapMode),
	TK_OPTION_NULL_OK|TK_OPTION_ENUM_VAR, wrapStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389







-
+







	}
	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 3, objv,
		    "tagName index1 ?index2 index1 index2 ...?");
	    return TCL_ERROR;
	}
	tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL);
	if (tagPtr->elide) {
	if (tagPtr->elide > 0) {
		/*
		* Indices are potentially obsolete after adding or removing
		* elided character ranges, especially indices having "display"
		* or "any" submodifier, therefore increase the epoch.
		*/
		textPtr->sharedTextPtr->stateEpoch++;
	}
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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
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







-
+













-
+




-
+









-
-
-
+













-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-












-
-
-
-
-
-

-
-
-
-
-







	} else {
	    Tcl_Obj *objPtr;

	    tagPtr = FindTag(interp, textPtr, objv[3]);
	    if (tagPtr == NULL) {
		return TCL_ERROR;
	    }
	    objPtr = Tk_GetOptionValue(interp, tagPtr,
	    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 ...?");
		    "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, tagPtr,
	    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, tagPtr, tagPtr->optionTable,
	    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
	     * because we need to distinguish a particular value of an option
	     * from "unspecified").
	     */

	    if (tagPtr->borderWidth < 0) {
		tagPtr->borderWidth = 0;
	    }
	    if (tagPtr->reliefString != NULL) {
		if (Tk_GetRelief(interp, tagPtr->reliefString,
			&tagPtr->relief) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->justifyString != NULL) {
		if (Tk_GetJustify(interp, tagPtr->justifyString,
			&tagPtr->justify) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->lMargin1String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->lMargin2String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->offsetString != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->offsetString,
			&tagPtr->offset) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->overstrikeString != NULL) {
		if (Tcl_GetBoolean(interp, tagPtr->overstrikeString,
			&tagPtr->overstrike) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->rMarginString != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) {
		    return TCL_ERROR;
		}
	    }
	    if (tagPtr->spacing1String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (tagPtr->spacing1 < 0) {
		    tagPtr->spacing1 = 0;
		}
	    }
	    if (tagPtr->spacing2String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (tagPtr->spacing2 < 0) {
		    tagPtr->spacing2 = 0;
		}
	    }
	    if (tagPtr->spacing3String != NULL) {
		if (Tk_GetPixels(interp, textPtr->tkwin,
			tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) {
		    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++;
522
523
524
525
526
527
528
529
530





531
532
533
534
535
536
537
636
637
638
639
640
641
642


643
644
645
646
647
648
649
650
651
652
653
654







-
-
+
+
+
+
+







		    || (tagPtr->lMargin2String != NULL)
		    || (tagPtr->offsetString != NULL)
		    || (tagPtr->rMarginString != NULL)
		    || (tagPtr->spacing1String != NULL)
		    || (tagPtr->spacing2String != NULL)
		    || (tagPtr->spacing3String != NULL)
		    || (tagPtr->tabStringPtr != NULL)
		    || (tagPtr->tabStyle != TK_TEXT_TABSTYLE_NONE)
		    || (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) {
		    || (tagPtr->tabStyle == TK_TEXT_TABSTYLE_TABULAR)
		    || (tagPtr->tabStyle == TK_TEXT_TABSTYLE_WORDPROCESSOR)
		    || (tagPtr->wrapMode == TEXT_WRAPMODE_CHAR)
		    || (tagPtr->wrapMode == TEXT_WRAPMODE_NONE)
		    || (tagPtr->wrapMode == TEXT_WRAPMODE_WORD)) {
		tagPtr->affectsDisplay = 1;
		tagPtr->affectsDisplayGeometry = 1;
	    }
	    if ((tagPtr->border != NULL)
		    || (tagPtr->selBorder != NULL)
		    || (tagPtr->reliefString != NULL)
		    || (tagPtr->bgStipple != None)
557
558
559
560
561
562
563
564

565
566
567
568
569
570
571
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688







-
+







		 * this for all peers, unless we actually want to synchronize
		 * sel-style changes across the peers.
		 */

		TkTextRedrawTag(textPtr->sharedTextPtr, NULL,
			NULL, NULL, tagPtr, 1);
	    }
	    return result;
	    return TCL_OK;
	}
	break;
    }
    case TAG_DELETE: {
	Tcl_HashEntry *hPtr;

	if (objc < 4) {
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
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







-
+





-
+

-
+

-
+


-
+

-
+


-
+




-
+

-
+

-
+




-
+


-
+







    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->relief = TK_RELIEF_NULL;
    tagPtr->bgStipple = None;
    tagPtr->fgColor = NULL;
    tagPtr->tkfont = NULL;
    tagPtr->fgStipple = None;
    tagPtr->justifyString = NULL;
    tagPtr->justify = TK_JUSTIFY_LEFT;
    tagPtr->justify = (Tk_Justify)-1;
    tagPtr->lMargin1String = NULL;
    tagPtr->lMargin1 = 0;
    tagPtr->lMargin1 = INT_MIN;
    tagPtr->lMargin2String = NULL;
    tagPtr->lMargin2 = 0;
    tagPtr->lMargin2 = INT_MIN;
    tagPtr->lMarginColor = NULL;
    tagPtr->offsetString = NULL;
    tagPtr->offset = 0;
    tagPtr->offset = INT_MIN;
    tagPtr->overstrikeString = NULL;
    tagPtr->overstrike = 0;
    tagPtr->overstrike = -1;
    tagPtr->overstrikeColor = NULL;
    tagPtr->rMarginString = NULL;
    tagPtr->rMargin = 0;
    tagPtr->rMargin = INT_MIN;
    tagPtr->rMarginColor = NULL;
    tagPtr->selBorder = NULL;
    tagPtr->selFgColor = NULL;
    tagPtr->spacing1String = NULL;
    tagPtr->spacing1 = 0;
    tagPtr->spacing1 = INT_MIN;
    tagPtr->spacing2String = NULL;
    tagPtr->spacing2 = 0;
    tagPtr->spacing2 = INT_MIN;
    tagPtr->spacing3String = NULL;
    tagPtr->spacing3 = 0;
    tagPtr->spacing3 = INT_MIN;
    tagPtr->tabStringPtr = NULL;
    tagPtr->tabArrayPtr = NULL;
    tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE;
    tagPtr->underlineString = NULL;
    tagPtr->underline = 0;
    tagPtr->underline = -1;
    tagPtr->underlineColor = NULL;
    tagPtr->elideString = NULL;
    tagPtr->elide = 0;
    tagPtr->elide = -1;
    tagPtr->wrapMode = TEXT_WRAPMODE_NULL;
    tagPtr->affectsDisplay = 0;
    tagPtr->affectsDisplayGeometry = 0;
    textPtr->sharedTextPtr->numTags++;
    if (!strcmp(tagName, "sel")) {
	tagPtr->textPtr = textPtr;
	textPtr->refCount++;
1104
1105
1106
1107
1108
1109
1110
1111

1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1221
1222
1223
1224
1225
1226
1227

1228
1229
1230

1231
1232
1233
1234
1235
1236
1237
1238







-
+


-
+







    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;
    int len;
    const char *str;

    str = TkGetStringFromObj(tagName, &len);
    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);
1453
1454
1455
1456
1457
1458
1459
1460

1461
1462

1463
1464
1465
1466
1467
1468
1469
1570
1571
1572
1573
1574
1575
1576

1577
1578

1579
1580
1581
1582
1583
1584
1585
1586







-
+

-
+







     * 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;
	unsigned int mask;

	mask = Tk_GetButtonMask(eventPtr->xbutton.button);
	mask = TkGetButtonMask(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) {
1477
1478
1479
1480
1481
1482
1483
1484
1485


1486





1487

1488















1489
1490
1491
1492
1493
1494
1495
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







-
-
+
+

+
+
+
+
+
-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	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)

    if ((textPtr->sharedTextPtr->bindingTable != NULL)
	    && (textPtr->tkwin != NULL) && !(textPtr->flags & DESTROYED)) {
	if (textPtr->numCurTags > 0) {
	    /*
	     * The mouse is inside the text widget, the 'current' mark was updated.
	     */

	TagBindEvent(textPtr, eventPtr, textPtr->numCurTags,
	    TagBindEvent(textPtr, eventPtr, textPtr->numCurTags,
		textPtr->curTagArrayPtr);
	} else if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
	    /*
	     * Key events fire independently of the 'current' mark and use the
	     * 'insert' mark.
	     */

	    TkTextIndex index;
	    TkTextTag** tagArrayPtr;
	    int numTags;

	    TkTextMarkNameToIndex(textPtr, "insert", &index);
	    tagArrayPtr = TkBTreeGetTags(&index, textPtr, &numTags);
	    SortTags(numTags, tagArrayPtr);
	    TagBindEvent(textPtr, eventPtr, numTags, tagArrayPtr);
	}
    }
    if (repick) {
	unsigned int oldState;

	oldState = eventPtr->xbutton.state;
	eventPtr->xbutton.state &= ~(unsigned long)ALL_BUTTONS;
	if (!(textPtr->flags & DESTROYED)) {
1536
1537
1538
1539
1540
1541
1542
1543

1544
1545
1546
1547
1548
1549
1550
1551
1673
1674
1675
1676
1677
1678
1679

1680

1681
1682
1683
1684
1685
1686
1687







-
+
-







				 * ButtonRelease, or MotionNotify. */
{
    TkTextIndex index;
    TkTextTag **oldArrayPtr, **newArrayPtr;
    TkTextTag **copyArrayPtr = NULL;
				/* Initialization needed to prevent compiler
				 * warning. */
    int numOldTags, numNewTags, i, j, nearby;
    int numOldTags, numNewTags, i, j, size, 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.
     */
1663
1664
1665
1666
1667
1668
1669

1670
1671
1672










1673
1674
1675
1676
1677
1678
1679
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







+
-
-
-
+
+
+
+
+
+
+
+
+
+







	if ((textPtr->sharedTextPtr->bindingTable != NULL)
		&& (textPtr->tkwin != NULL)
		&& !(textPtr->flags & DESTROYED)) {
	    event = textPtr->pickEvent;
	    event.type = LeaveNotify;

	    /*
	     * Behaviour before ticket #47d4f29159:
	     * Always use a detail of NotifyAncestor. Besides being
	     * consistent, this avoids problems where the binding code will
	     * discard NotifyInferior events.
	     *   Always use a detail of NotifyAncestor. Besides being
	     *   consistent, this avoids problems where the binding code will
	     *   discard NotifyInferior events.
	     *
	     * Behaviour after ticket #47d4f29159:
	     *   The binding mechanism doesn't discard events with detail field
	     *   NotifyInferior anymore. It would be best to base the detail
	     *   field on the ancestry relationship between the old and new
	     *   tags. For the time being, retain the choice from before
	     *   ticket #47d4f29159, which doesn't harm.
	     */

	    event.xcrossing.detail = NotifyAncestor;
	    TagBindEvent(textPtr, &event, numOldTags, oldArrayPtr);
	}
	ckfree(oldArrayPtr);
    }
Changes to generic/tkTextWind.c.
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
24
25
26
27
28
29
30

31
32
33
34
35
36
37


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67







-
+






-
-
+
+




















-
+







			    Tk_Window tkwin);
static void		EmbWinLostContentProc(ClientData clientData,
			    Tk_Window tkwin);

static const Tk_GeomMgr textGeomType = {
    "text",			/* name */
    EmbWinRequestProc,		/* requestProc */
    EmbWinLostContentProc,	/* lostContentProc */
    EmbWinLostContentProc,	/* lostSlaveProc */
};

/*
 * Macro that determines the size of an embedded window segment:
 */

#define EW_SEG_SIZE (offsetof(TkTextSegment, body) \
	+ sizeof(TkTextEmbWindow))
#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,
			    TkSizeT offset, int maxX, TkSizeT maxChars,int noCharsYet,
			    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);
95
96
97
98
99
100
101
102

103
104
105

106
107

108
109

110
111

112
113

114
115
116
117
118
119
120
95
96
97
98
99
100
101

102
103
104

105
106

107
108

109
110

111
112

113
114
115
116
117
118
119
120







-
+


-
+

-
+

-
+

-
+

-
+








/*
 * 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),
	"center", -1, Tk_Offset(TkTextEmbWindow, align),
	0, alignStrings, 0},
    {TK_OPTION_STRING, "-create", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, create), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(TkTextEmbWindow, create), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padX), 0, 0, 0},
	"0", -1, Tk_Offset(TkTextEmbWindow, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, padY), 0, 0, 0},
	"0", -1, Tk_Offset(TkTextEmbWindow, padY), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-stretch", NULL, NULL,
	"0", TCL_INDEX_NONE, offsetof(TkTextEmbWindow, stretch), 0, 0, 0},
	"0", -1, Tk_Offset(TkTextEmbWindow, stretch), 0, 0, 0},
    {TK_OPTION_WINDOW, "-window", NULL, NULL,
	NULL, TCL_INDEX_NONE, offsetof(TkTextEmbWindow, tkwin), TK_OPTION_NULL_OK, 0, 0},
	NULL, -1, Tk_Offset(TkTextEmbWindow, tkwin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
 * TkTextWindowCmd --
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200







-
+







	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,
	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;
    }
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241







-
+







	    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,
	    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;
397
398
399
400
401
402
403
404

405
406
407
408
409
410
411
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411







-
+







    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,
    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) {
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
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 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;
    }

    hPtr = Tcl_FindHashEntry(&ewPtr->body.ew.sharedTextPtr->windowTable,
	    Tk_PathName(client->tkwin));
    if (hPtr != NULL) {
	/*
	 * This may not exist if the entire widget is being deleted.
	 */

	Tcl_DeleteHashEntry(hPtr);
    }

    ewPtr->body.ew.tkwin = NULL;
    client->tkwin = NULL;
    index.tree = ewPtr->body.ew.sharedTextPtr->tree;
    index.linePtr = ewPtr->body.ew.linePtr;
    index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
    TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
    EmbWinRequestProc(client, NULL);
	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinRequestProc --
 *
570
571
572
573
574
575
576
577

578
579
580
581
582
583
584








585

586
587
588
589
590
591
592
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







-
+







+
+
+
+
+
+
+
+
-
+







 *
 *--------------------------------------------------------------
 */

static void
EmbWinRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    TCL_UNUSED(Tk_Window))		/* Window that changed its desired size. */
    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;

    /*
     * ewPtr->body.ew.tkwin == NULL means the embedded window is already
     * destroyed. The ewPtr segment is no longer linked, TkTextSegToOffset
     * cannot find it within the line pointed by ewPtr->body.ew.linePtr.
     */

    index.byteIndex =  ewPtr->body.ew.tkwin ?
    index.byteIndex = TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr);
	    TkTextSegToOffset(ewPtr, ewPtr->body.ew.linePtr) : 0;
    TkTextChanged(ewPtr->body.ew.sharedTextPtr, NULL, &index, &index);
    TkTextInvalidateLineMetrics(ewPtr->body.ew.sharedTextPtr, NULL,
	    index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY);
}

/*
 *--------------------------------------------------------------
813
814
815
816
817
818
819
820

821
822
823
824

825
826
827
828
829
830
831
815
816
817
818
819
820
821

822
823
824
825

826
827
828
829
830
831
832
833







-
+



-
+







 */

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
    int 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
    TCL_UNUSED(int),	/* 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)
1049
1050
1051
1052
1053
1054
1055
1056

1057
1058
1059
1060
1061
1062
1063
1051
1052
1053
1054
1055
1056
1057

1058
1059
1060
1061
1062
1063
1064
1065







-
+







    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);
	Tcl_Panic("EmbWinCheckProc: embedded window has size %d", ewPtr->size);
    }
}

/*
 *--------------------------------------------------------------
 *
 * TkTextEmbWinDisplayProc --
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
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







-
-
-
+
+
+

















-
+




-
+






+
+
+
+
+
+
+
+
+
+
+
-
+







 *
 * TkTextWindowIndex --
 *
 *	Given the name of an embedded window within a text widget, returns an
 *	index corresponding to the window's position in the text.
 *
 * Results:
 *	The return value is 1 if there is an embedded window by the given name
 *	in the text widget, 0 otherwise. If the window exists, *indexPtr is
 *	filled in with its index.
 *	The return value is TCL_OK if there is an embedded window by the given
 *	name in the text widget, TCL_ERROR otherwise. If the window exists,
 *	*indexPtr is filled in with its index.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkTextWindowIndex(
    TkText *textPtr,		/* Text widget containing window. */
    const char *name,		/* Name of window. */
    TkTextIndex *indexPtr)	/* Index information gets stored here. */
{
    Tcl_HashEntry *hPtr;
    TkTextSegment *ewPtr;

    if (textPtr == NULL) {
	return 0;
	return TCL_ERROR;
    }

    hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name);
    if (hPtr == NULL) {
	return 0;
	return TCL_ERROR;
    }

    ewPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr);
    indexPtr->tree = textPtr->sharedTextPtr->tree;
    indexPtr->linePtr = ewPtr->body.ew.linePtr;
    indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr);

    /*
     * If indexPtr refers to somewhere outside the -startline/-endline
     * range limits of the widget, error out since the window indeed is not
     * reachable from this text widget (it may be reachable from a peer).
     */

    if (TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 1) == TCL_ERROR) {
	return TCL_ERROR;
    }

    return 1;
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EmbWinGetClient --
 *
Changes to generic/tkTrig.c.
35
36
37
38
39
40
41
42
43
44



45
46
47
48
49
50
51
35
36
37
38
39
40
41



42
43
44
45
46
47
48
49
50
51







-
-
-
+
+
+







 *	None.
 *
 *--------------------------------------------------------------
 */

double
TkLineToPoint(
    double end1Ptr[2],		/* Coordinates of first end-point of line. */
    double end2Ptr[2],		/* Coordinates of second end-point of line. */
    double pointPtr[2])		/* Points to coords for point. */
    double end1Ptr[],		/* Coordinates of first end-point of line. */
    double end2Ptr[],		/* Coordinates of second end-point of line. */
    double pointPtr[])		/* Points to coords for point. */
{
    double x, y;

    /*
     * Compute the point on the line that is closest to the point. This must
     * be done separately for vertical edges, horizontal edges, and other
     * edges.
139
140
141
142
143
144
145
146

147
148

149
150

151
152
153
154
155
156
157
139
140
141
142
143
144
145

146
147

148
149

150
151
152
153
154
155
156
157







-
+

-
+

-
+







 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkLineToArea(
    double end1Ptr[2],		/* X and y coordinates for one endpoint of
    double end1Ptr[],		/* X and y coordinates for one endpoint of
				 * line. */
    double end2Ptr[2],		/* X and y coordinates for other endpoint of
    double end2Ptr[],		/* X and y coordinates for other endpoint of
				 * line. */
    double rectPtr[4])		/* Points to coords for rectangle, in the
    double rectPtr[])		/* Points to coords for rectangle, in the
				 * order x1, y1, x2, y2. X1 must be no larger
				 * than x2, and y1 no larger than y2. */
{
    int inside1, inside2;

    /*
     * First check the two points individually to see whether they are inside
278
279
280
281
282
283
284

285
286
287
288
289
290
291
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292







+







 *
 * 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?
647
648
649
650
651
652
653

654
655
656

657
658
659
660
661
662
663

664
665
666
667
668
669
670
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







+


-
+






-
+







 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
double
TkOvalToPoint(
    double ovalPtr[4],		/* Pointer to array of four coordinates (x1,
    double ovalPtr[],		/* Pointer to array of four coordinates (x1,
				 * y1, x2, y2) defining oval's bounding
				 * box. */
    double width,		/* Width of outline for oval. */
    int filled,			/* Non-zero means oval should be treated as
				 * filled; zero means only consider
				 * outline. */
    double pointPtr[2])		/* Coordinates of point. */
    double pointPtr[])		/* Coordinates of point. */
{
    double xDelta, yDelta, scaledDistance, distToOutline, distToCenter;
    double xDiam, yDiam;

    /*
     * Compute the distance between the center of the oval and the point in
     * question, using a coordinate system where the oval has been transformed
861
862
863
864
865
866
867

868
869
870
871
872
873
874
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877







+







 *
 * Side effects:
 *	The boudn.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
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. */
{
Changes to generic/tkUndo.c.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
1
2
3
4
5


6
7
8
9
10
11
12
13
14





-
-
+
+







/*
 * tkUndo.c --
 *
 *	This module provides the implementation of an undo stack.
 *
 * Copyright (c) 2002 by Ludwig Callewaert.
 * Copyright (c) 2003-2004 by Vincent Darley.
 * Copyright (c) 2002 Ludwig Callewaert.
 * Copyright (c) 2003-2004 Vincent Darley.
 *
 * 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"
Changes to generic/tkUtil.c.
9
10
11
12
13
14
15




16
17
18
19
20
21
22
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"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * 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 */
44
45
46
47
48
49
50
51

52
53
54

55
56
57
58
59
60
61
48
49
50
51
52
53
54

55
56
57

58
59
60
61
62
63
64
65







-
+


-
+







 *--------------------------------------------------------------
 */

int
TkStateParseProc(
    ClientData clientData,	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    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. */
    int offset)			/* Offset into item. */
{
    int c;
    int flags = PTR2INT(clientData);
    size_t length;
    Tcl_Obj *msgObj;
    Tk_State *statePtr = (Tk_State *) (widgRec + offset);

121
122
123
124
125
126
127
128
129


130
131
132


133
134
135
136
137
138
139
125
126
127
128
129
130
131


132
133
134


135
136
137
138
139
140
141
142
143







-
-
+
+

-
-
+
+







 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkStatePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* 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
    int offset,			/* Offset into item. */
    Tcl_FreeProc **freeProcPtr)	/* 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:
165
166
167
168
169
170
171
172

173
174

175
176
177

178
179
180
181
182
183
184
169
170
171
172
173
174
175

176
177

178
179
180

181
182
183
184
185
186
187
188







-
+

-
+


-
+







 *	indicated in the value argument.
 *
 *--------------------------------------------------------------
 */

int
TkOrientParseProc(
    TCL_UNUSED(void *),	/* some flags.*/
    ClientData clientData,	/* some flags.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    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. */
    int offset)			/* Offset into item. */
{
    int c;
    size_t length;
    int *orientPtr = (int *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*orientPtr = 0;
223
224
225
226
227
228
229
230
231


232
233
234


235
236
237
238
239
240
241
227
228
229
230
231
232
233


234
235
236


237
238
239
240
241
242
243
244
245







-
-
+
+

-
-
+
+







 *	None.
 *
 *--------------------------------------------------------------
 */

const char *
TkOrientPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* 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
    int offset,			/* Offset into item. */
    Tcl_FreeProc **freeProcPtr)	/* 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";
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276







-
+







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 */
    int 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;

405
406
407
408
409
410
411
412
413


414
415

416
417
418
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
409
410
411
412
413
414
415


416
417
418

419
420
421
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
437







-
-
+
+

-
+










-
+







 *	The offset of the tile is returned.
 *
 *----------------------------------------------------------------------
 */

const char *
TkOffsetPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    ClientData clientData,	/* not used */
    Tk_Window tkwin,		/* not used */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset,			/* Offset of tile in 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);
	snprintf(p, 32, "%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";
	} else if (offsetPtr->flags & TK_OFFSET_CENTER) {
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
456
457
458
459
460
461
462

463
464
465
466
467
468
469
470







-
+







	    return "se";
	}
    }
    q = p = (char *)ckalloc(32);
    if (offsetPtr->flags & TK_OFFSET_RELATIVE) {
	*q++ = '#';
    }
    sprintf(q, "%d,%d", offsetPtr->xoffset, offsetPtr->yoffset);
    snprintf(q, 32, "%d,%d", offsetPtr->xoffset, offsetPtr->yoffset);
    *freeProcPtr = TCL_DYNAMIC;
    return p;
}

/*
 *----------------------------------------------------------------------
 *
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
479
480
481
482
483
484
485

486
487
488
489
490
491
492
493







-
+







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 */
    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)) {
506
507
508
509
510
511
512
513
514


515
516

517
518
519
520
521
522
523
510
511
512
513
514
515
516


517
518
519

520
521
522
523
524
525
526
527







-
-
+
+

-
+







 *	The name of the tile is returned.
 *
 *----------------------------------------------------------------------
 */

const char *
TkPixelPrintProc(
    TCL_UNUSED(void *),	/* not used */
    TCL_UNUSED(Tk_Window),		/* not used */
    ClientData clientData,	/* not used */
    Tk_Window tkwin,		/* not used */
    char *widgRec,		/* Widget structure record */
    TkSizeT offset,			/* Offset of tile in 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;
612
613
614
615
616
617
618
































































619
620
621
622
623
624
625
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







{
    TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkDrawDottedRect --
 *
 *	This function draws a dotted rectangle, used as focus ring of Ttk
 *	widgets and for rendering the active element of a listbox.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A dotted rectangle is drawn in the specified Drawable.  On the
 *	windowing systems x11 and aqua the GC components line_style,
 *	line_width, dashes, and dash_offset are modified as needed.
 *
 *----------------------------------------------------------------------
 */

void
TkDrawDottedRect(
    Display *disp,		/* Display containing the dotted rectangle. */
    Drawable d,			/* Where to draw the rectangle (typically a
				 * pixmap for double buffering). */
    GC gc,			/* Graphics context to use for drawing the
				 * rectangle. */
    int x, int y,		/* Coordinates of the top-left corner. */
    int width, int height)	/* Width & height, _including the border_. */
{
#ifdef _WIN32
    TkWinDrawDottedRect(disp, d, gc->foreground, x, y, width, height);

#else
    XGCValues gcValues;
    int widthMod2 = width % 2, heightMod2 = height % 2;
    int x2 = x + width - 1, y2 = y + height - 1;

    gcValues.line_style = LineOnOffDash;
    gcValues.line_width = 1;
    gcValues.dashes = 1;
#ifdef MAC_OSX_TK
    gcValues.dash_offset = 1;
#else
    gcValues.dash_offset = 0;
#endif
    XChangeGC(disp, gc, GCLineStyle | GCLineWidth | GCDashList | GCDashOffset,
	    &gcValues);

    if (widthMod2 == 0 && heightMod2 == 0) {
	XDrawLine(disp, d, gc, x+1, y,  x2-1, y);	/* N */
	XDrawLine(disp, d, gc, x+2, y2, x2,   y2);	/* S */
	XDrawLine(disp, d, gc, x,  y+2, x,  y2);	/* W */
	XDrawLine(disp, d, gc, x2, y+1, x2, y2-1);	/* E */
    } else {
	int dx = 1 - widthMod2, dy = 1 - heightMod2;

	XDrawLine(disp, d, gc, x+1, y,  x2-dx, y);	/* N */
	XDrawLine(disp, d, gc, x+1, y2, x2-dx, y2);	/* S */
	XDrawLine(disp, d, gc, x,  y+1, x,  y2-dy);	/* W */
	XDrawLine(disp, d, gc, x2, y+1, x2, y2-dy);	/* E */
    }
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetScrollInfo --
 *
 *	This function is invoked to parse "xview" and "yview" scrolling
 *	commands for widgets using the new scrolling command syntax ("moveto"
 *	or "scroll" options).
 *
 * Results:
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
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







-



-
+



-
+


-









-
+







	}
	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"));
		    argv[0], argv[1], "scroll number units|pages"));
	    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) {
	if (Tcl_GetInt(interp, argv[3], intPtr) != 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]));
		"bad argument \"%s\": must be units or pages", 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);
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
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







-
-
+
+














-

-
+


-
+


-
-
-
-
-
-
+
+
+







-
+







    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);
    const char *arg = Tcl_GetString(objv[2]);
    size_t length = 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");
	    Tcl_WrongNumArgs(interp, 2, objv, "scroll number units|pages");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[3], &d) != TCL_OK) {
	if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
	    return TK_SCROLL_ERROR;
	}
	*intPtr = (d >= 0) ? ceil(d) : floor(d);
	if (dblPtr) {
	    *dblPtr = d;
	}

	arg = TkGetStringFromObj(objv[4], &length);

	arg = Tcl_GetString(objv[4]);
	length = 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));
		"bad argument \"%s\": must be units or pages", 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;
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
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







-
+












-
+














+




+
-
+



















-
+







-
+
-
-
+
-
-
-
-

-
-
+
+







    Tcl_DStringFree(&ds);
    return ensemble;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_SendVirtualEvent --
 * TkSendVirtualEvent --
 *
 * 	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(
TkSendVirtualEvent(
    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;
    if (detail) Tcl_IncrRefCount(detail); // Event code will DecrRefCount

    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

/* Tcl 8.6 has a different definition of Tcl_UniChar than other Tcl versions for TCL_UTF_MAX > 3 */
#if TCL_UTF_MAX <= 4
#if TCL_UTF_MAX <= (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6))
/*
 *---------------------------------------------------------------------------
 *
 * 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
int
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);
    int len = Tcl_UtfToUniChar(src, &uniChar);
    if ((sizeof(Tcl_UniChar) == 2)
	    && ((uniChar & 0xFC00) == 0xD800)
    if ((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 */
	/* This can only happen if sizeof(Tcl_UniChar)== 2 and src points
	 * to a character > U+FFFF  */
	size_t len2 = Tcl_UtfToUniChar(src+len, &low);
	if ((low & 0xFC00) == 0xDC00) {
	    *chPtr = (((uniChar & 0x3FF) << 10) | (low & 0x3FF)) + 0x10000;
	    return len + len2;
	}
    }
    *chPtr = uniChar;
1259
1260
1261
1262
1263
1264
1265
1266

1267
1268

1269
1270
1271
1272
1273
1274
1275
1318
1319
1320
1321
1322
1323
1324

1325
1326

1327
1328
1329
1330
1331
1332
1333
1334







-
+

-
+







 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

size_t TkUniCharToUtf(int ch, char *buf)
int TkUniCharToUtf(int ch, char *buf)
{
    if ((sizeof(Tcl_UniChar) == 2) && (((unsigned)(ch - 0x10000) <= 0xFFFFF))) {
    if ((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);
}
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
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







+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
-
-
+
+
+







	return src - 4;
    }
#endif

    return (first + TkUtfToUniChar(first, &ch) >= src) ? first : p ;
}

/*
 *---------------------------------------------------------------------------
 *
#endif

#if TCL_MAJOR_VERSION > 8
unsigned char *
TkGetByteArrayFromObj(
 * TkUtfAtIndex --
 *
 *	Returns a pointer to the specified character (not byte) position in
 *	a CESU-8 string.  This will never point at a low surrogate.
 *
 * Results:
 *	As above.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

const char *
TkUtfAtIndex(
	Tcl_Obj *objPtr,
	size_t *lengthPtr
) {
    unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, NULL);
    const char *src,	/* The UTF-8 string. */
    int index)		/* The position of the desired character. */
{
    int ch;
    const char *p = Tcl_UtfAtIndex(src, index);
    *lengthPtr = *(size_t *) objPtr->internalRep.twoPtrValue.ptr1;
    return result;
}
    if ((p > src) && (UCHAR(p[-1]) >= 0xF0)) {
	--p;
	return p + TkUtfToUniChar(p, &ch);
    }
#endif /* TCL_MAJOR_VERSION > 8 */

    return p;
}
#endif
/*
 * 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
16
17
18
19
20
21
22


23
24
25

26
27
28
29
30
31
32
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
    const char *name;		/* Textual name of class. */
    int minLength;		/* Minimum # characters that must be specified
				 * for an unambiguous match. */
    short c_class;			/* X symbol for class. */
    int 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},
    {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. */
    size_t refCount;		/* How many uses of the colormap are still
    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
189
190
191
192
193
194
195
196
197


198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
189
190
191
192
193
194
195


196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215







-
-
+
+










-
+







	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)
	for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) {
	    if ((dictPtr->name[0] == c) && (length >= (size_t)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++) {
	    for (dictPtr = visualNames; dictPtr->name != NULL; 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;
	}
Changes to generic/tkWindow.c.
15
16
17
18
19
20
21

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







+







#include "tkInt.h"
#include "tkPort.h"
#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#endif
#include "tkUuid.h"

/*
 * Type used to keep track of Window objects that were only partially
 * deallocated by Tk_DestroyWindow.
 */

#define HD_CLEANUP		1
89
90
91
92
93
94
95

96
97
98
99
100
101
102
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104







+







 * the C functions that execute them.
 */

#define ISSAFE 1
#define PASSMAINWINDOW 2
#define WINMACONLY 4
#define USEINITPROC 8
#define SAVEUPDATECMD 16 /* better only be one of these! */

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;
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138







-
+







    {"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},
    {"update",		Tk_UpdateObjCmd,	PASSMAINWINDOW|ISSAFE|SAVEUPDATECMD},
    {"winfo",		Tk_WinfoObjCmd,		PASSMAINWINDOW|ISSAFE},
    {"wm",		Tk_WmObjCmd,		PASSMAINWINDOW},

    /*
     * Default widget class commands.
     */

234
235
236
237
238
239
240


241
242
243
244
245
246
247
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251







+
+







 */

static void
TkCloseDisplay(
    TkDisplay *dispPtr)
{
    TkClipCleanup(dispPtr);

    TkpCancelWarp(dispPtr);

    if (dispPtr->name != NULL) {
	ckfree(dispPtr->name);
    }

    if (dispPtr->atomInit) {
	Tcl_DeleteHashTable(&dispPtr->nameTable);
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

360

361
362
363
364
365
366
367
334
335
336
337
338
339
340

341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371







-



-


















+

+







	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.
     */

#ifdef TK_USE_INPUT_METHODS
    winPtr->ximGeneration = 0;
#endif /*TK_USE_INPUT_METHODS*/
    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.
648
649
650
651
652
653
654

655
656

657
658
659
660
661
662
663
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669







+


+







	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->ximGeneration = 0;
    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->geomMgrName = NULL;
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
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







+
+
+
+
+

















+







 *	with the window and registered for "send" commands under "baseName".
 *	BaseName may be extended with an instance number in the form "#2" if
 *	necessary to make it globally unique. Tk-related commands are bound
 *	into interp.
 *
 *----------------------------------------------------------------------
 */

#ifndef STRINGIFY
#  define STRINGIFY(x) STRINGIFY1(x)
#  define STRINGIFY1(x) #x
#endif

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;
    Tcl_CmdInfo info;
    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).
     */
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878

879
880
881
882
883
884
885
874
875
876
877
878
879
880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897







-









+







    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);
    TkFontPkgInit(mainPtr);
    TkStylePkgInit(mainPtr);
    mainPtr->tlFocusPtr = NULL;
    mainPtr->displayFocusPtr = NULL;
    mainPtr->optionRootPtr = NULL;
    Tcl_InitHashTable(&mainPtr->imageTable, TCL_STRING_KEYS);
    mainPtr->strictMotif = 0;
    mainPtr->alwaysShowSelection = 0;
    mainPtr->tclUpdateObjProc = NULL;
    if (Tcl_LinkVar(interp, "tk_strictMotif", (char *) &mainPtr->strictMotif,
	    TCL_LINK_BOOLEAN) != TCL_OK) {
	Tcl_ResetResult(interp);
    }
    if (Tcl_CreateNamespace(interp, "::tk", NULL, NULL) == NULL) {
	Tcl_ResetResult(interp);
    }
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
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







+
+



















+
+
+
+
+









+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








    /*
     * Bind in Tk's commands.
     */

    isSafe = Tcl_IsSafe(interp);
    for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
	Tcl_CmdInfo cmdInfo;

	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 & SAVEUPDATECMD) &&
	    Tcl_GetCommandInfo(interp, cmdPtr->name, &cmdInfo) &&
	    cmdInfo.isNativeObjectProc && !cmdInfo.objClientData && !cmdInfo.deleteProc) {
	    mainPtr->tclUpdateObjProc = cmdInfo.objProc;
	}
	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);
	}
    }
    if (Tcl_GetCommandInfo(interp, "::tcl::build-info", &info)) {
	Tcl_CreateObjCommand(interp, "::tk::build-info",
		info.objProc, (void *)
		(TK_PATCH_LEVEL "+" STRINGIFY(TK_VERSION_UUID)
#if defined(MAC_OSX_TK)
		".aqua"
#endif
#if defined(__clang__) && defined(__clang_major__)
		".clang-" STRINGIFY(__clang_major__)
#if __clang_minor__ < 10
		"0"
#endif
		STRINGIFY(__clang_minor__)
#endif
#if defined(__cplusplus) && !defined(__OBJC__)
		".cplusplus"
#endif
#ifndef NDEBUG
		".debug"
#endif
#if !defined(__clang__) && !defined(__INTEL_COMPILER) && defined(__GNUC__)
		".gcc-" STRINGIFY(__GNUC__)
#if __GNUC_MINOR__ < 10
		"0"
#endif
		STRINGIFY(__GNUC_MINOR__)
#endif
#ifdef __INTEL_COMPILER
		".icc-" STRINGIFY(__INTEL_COMPILER)
#endif
#ifdef TCL_MEM_DEBUG
		".memdebug"
#endif
#if defined(_MSC_VER)
		".msvc-" STRINGIFY(_MSC_VER)
#endif
#ifdef USE_NMAKE
		".nmake"
#endif
#ifdef TK_NO_DEPRECATED
		".no-deprecate"
#endif
#ifndef TCL_CFG_OPTIMIZED
		".no-optimize"
#endif
#ifdef __OBJC__
		".objective-c"
#if defined(__cplusplus)
		"plusplus"
#endif
#endif
#ifdef TCL_CFG_PROFILED
		".profile"
#endif
#ifdef PURIFY
		".purify"
#endif
#ifdef STATIC_BUILD
		".static"
#endif
#if TCL_UTF_MAX <= (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6))
		".utf-16"
#endif
#if defined(_WIN32)
		".win32"
#endif
#if !defined(_WIN32) && !defined(MAC_OSX_TK)
		".x11"
#if !defined(HAVE_XFT)
		".no-xft"
#endif
#endif
		), NULL);
    }

    /*
     * Set variables for the interpreter.
     */

    Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY);
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
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







-
+
















-
+







				 * 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;
    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 = (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;
    numChars = (int) (p-pathName);
    if (numChars > FIXED_SPACE) {
	p = (char *)ckalloc(numChars + 1);
    } else {
	p = fixedSpace;
    }
    if (numChars == 0) {
	*p = '.';
1264
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1357
1358
1359
1360
1361
1362
1363

1364
1365
1366
1367
1368
1369
1370
1371







-
+







	halfdeadPtr->winPtr = winPtr;
	halfdeadPtr->nextPtr = tsdPtr->halfdeadWindowList;
	tsdPtr->halfdeadWindowList = halfdeadPtr;
    }

    /*
     * Some cleanup needs to be done immediately, rather than later, because
     * it needs information that will be destoyed before we get to the main
     * it needs information that will be destroyed before we get to the main
     * cleanup point. For example, TkFocusDeadWindow needs to access the
     * parentPtr field from a window, but if a Destroy event handler deletes
     * the window's parent this field will be NULL before the main cleanup
     * point is reached.
     */

    if (!(halfdeadPtr->flags & HD_FOCUS)) {
1435
1436
1437
1438
1439
1440
1441
1442

1443
1444
1445
1446

1447
1448

1449
1450
1451

1452
1453
1454
1455
1456
1457
1458
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







-
+




+

-
+



+







	     * to do an explicit destroy of this X window.
	     */

	    XDestroyWindow(winPtr->display, winPtr->window);
	}
#endif
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable,
		winPtr->window));
		(char *) winPtr->window));
	winPtr->window = None;
    }
    UnlinkWindow(winPtr);
    TkEventDeadWindow(winPtr);
#ifdef TK_USE_INPUT_METHODS
    if (winPtr->inputContext != NULL &&
	winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) {
	    winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) {
	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->geomMgrName != NULL) {
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
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







-
+

+
+
+
-
-
+
+
+
+
+
+
+
+
+















+







	     *
	     * 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)) {
		!Tcl_InterpDeleted(winPtr->mainPtr->interp)) {
		for (cmdPtr = commands; cmdPtr->name != NULL; cmdPtr++) {
		    if ((cmdPtr->flags & SAVEUPDATECMD) &&
			winPtr->mainPtr->tclUpdateObjProc != NULL) {
			/* Restore Tcl's version of [update] */
		    Tcl_CreateObjCommand(winPtr->mainPtr->interp, cmdPtr->name,
			    TkDeadAppObjCmd, NULL, NULL);
			Tcl_CreateObjCommand(winPtr->mainPtr->interp,
					     cmdPtr->name,
					     winPtr->mainPtr->tclUpdateObjProc,
					     NULL, NULL);
		    } else {
			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);
	    Ttk_TkDestroyedHandler(winPtr->mainPtr->interp);

	    /*
	     * 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
	     */
1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758







-
+







    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_HandleEvent(&event);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_MakeWindowExist --
 *
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1906
1907
1908
1909
1910
1911
1912

1913
1914
1915
1916
1917
1918
1919
1920







-
+







	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);
	Tk_HandleEvent(&event);
    }
}

void
Tk_ConfigureWindow(
    Tk_Window tkwin,		/* Window to re-configure. */
    unsigned int valueMask,	/* Mask indicating which parts of *valuePtr
2062
2063
2064
2065
2066
2067
2068



2069

2070
2071
2072
2073
2074
2075
2076
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186







+
+
+

+







void
Tk_DefineCursor(
    Tk_Window tkwin,		/* Window to manipulate. */
    Tk_Cursor cursor)		/* Cursor to use for window (may be None). */
{
    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;
    }
}
2348
2349
2350
2351
2352
2353
2354
2355

2356
2357
2358
2359
2360
2361
2362
2458
2459
2460
2461
2462
2463
2464

2465
2466
2467
2468
2469
2470
2471
2472







-
+







	    break;
	}
    }
    if (window == None) {
	return NULL;
    }

    hPtr = Tcl_FindHashEntry(&dispPtr->winTable, window);
    hPtr = Tcl_FindHashEntry(&dispPtr->winTable, (char *) window);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Tk_Window)Tcl_GetHashValue(hPtr);
}

/*
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
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







-
+

















-
+








    return tsdPtr->numMainWindows;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_AlwaysShowSelection --
 * 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
Tk_AlwaysShowSelection(
TkpAlwaysShowSelection(
    Tk_Window tkwin)		/* Window whose application is to be
				 * checked. */
{
    return ((TkWindow *) tkwin)->mainPtr->alwaysShowSelection;
}

/*
2780
2781
2782
2783
2784
2785
2786
2787
2788


2789
2790
2791
2792
2793
2794
2795
2890
2891
2892
2893
2894
2895
2896


2897
2898
2899
2900
2901
2902
2903
2904
2905







-
-
+
+







     * 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);
	    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.
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
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







-
+











-
+










-
+



-
+






-
+
-
-
-
-
-
-
+
+
+
-
-
-
+
-
+
+







    }

    tsdPtr->numMainWindows = 0;
    tsdPtr->mainWindowList = NULL;
    tsdPtr->initialized = 0;
}

#if defined(_WIN32)
#if defined(_WIN32) && !defined(STATIC_BUILD)

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
MODULE_SCOPE void
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;
    int len;
    void (*tkmainex)(int, char **, Tcl_AppInitProc *, Tcl_Interp *);

    /* construct "<path>/libtk8.?.dll", from "<path>/tk8?.dll" */
    len = GetModuleFileNameW(Tk_GetHINSTANCE(), name, MAX_PATH);
    len = GetModuleFileNameW((HINSTANCE)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) {
    if (tkcygwindll) {
	/* dll is not present */
	return 0;
    }
    tkmainex = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *))
	    (void *)GetProcAddress(tkcygwindll, "Tk_MainEx");
    if (!tkmainex) {
	tkmainex = (void (*)(int, char **, Tcl_AppInitProc *, Tcl_Interp *))
		(void *)GetProcAddress(tkcygwindll, "Tk_MainEx");
	if (tkmainex) {
	return 0;
    }
    tkmainex(argc, argv, appInitProc, interp);
	    tkmainex(argc, argv, appInitProc, interp);
    return 1;
	}
    }
}
#endif /* _WIN32 */

/*
 *----------------------------------------------------------------------
 *
 * Tk_Init --
2888
2889
2890
2891
2892
2893
2894
2895

2896
2897
2898
2899
2900
2901
2902
2994
2995
2996
2997
2998
2999
3000

3001
3002
3003
3004
3005
3006
3007
3008







-
+







 *----------------------------------------------------------------------
 */

int
Tk_Init(
    Tcl_Interp *interp)		/* Interpreter to initialize. */
{
#if defined(_WIN32)
#if defined(_WIN32) && !defined(STATIC_BUILD)
    if (tkcygwindll) {
	int (*tkinit)(Tcl_Interp *);

	tkinit = (int(*)(Tcl_Interp *))(void *)GetProcAddress(tkcygwindll,"Tk_Init");
	if (tkinit) {
	    return tkinit(interp);
	}
2961
2962
2963
2964
2965
2966
2967
2968

2969
2970
2971
2972
2973
2974
2975
3067
3068
3069
3070
3071
3072
3073

3074
3075
3076
3077
3078
3079
3080
3081







-
+







     * - 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 defined(_WIN32) && !defined(STATIC_BUILD)
    if (tkcygwindll) {
	int (*tksafeinit)(Tcl_Interp *);

	tksafeinit = (int (*)(Tcl_Interp *))
		(void *)GetProcAddress(tkcygwindll, "Tk_SafeInit");
	if (tksafeinit) {
	    return tksafeinit(interp);
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
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







-
+



-
-














+







 *	Depends on the initialization scripts that are invoked.
 *
 *----------------------------------------------------------------------
 */

static int
CopyValue(
    ClientData dummy,
    TCL_UNUSED(void *),
    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* appNameObj = 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;

3048
3049
3050
3051
3052
3053
3054
3055

3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3153
3154
3155
3156
3157
3158
3159

3160
3161
3162
3163






3164
3165
3166
3167
3168
3169
3170







-
+



-
-
-
-
-
-







	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) {
    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));
3092
3093
3094
3095
3096
3097
3098
3099

3100
3101
3102
3103
3104
3105
3106
3191
3192
3193
3194
3195
3196
3197

3198
3199
3200
3201
3202
3203
3204
3205







-
+







	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);
		Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_MASTER", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * Construct the name (rewalk...)
	 */
3188
3189
3190
3191
3192
3193
3194


3195
3196
3197
3198
3199
3200
3201
3202
3203
3204


3205
3206
3207
3208
3209
3210
3211
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







+
+








-
-
+
+







    if (nameObj == NULL) {
	Tcl_DString nameDS;

	Tcl_DStringInit(&nameDS);
	TkpGetAppName(interp, &nameDS);
	nameObj = Tcl_NewStringObj(Tcl_DStringValue(&nameDS),
		Tcl_DStringLength(&nameDS));
	appNameObj = nameObj;
	Tcl_IncrRefCount(appNameObj);
	Tcl_DStringFree(&nameDS);
    }

    /*
     * The -class argument is always the ToTitle of the -name
     */

    {
	TkSizeT numBytes;
	const char *bytes = TkGetStringFromObj(nameObj, &numBytes);
	int numBytes;
	const char *bytes = Tcl_GetStringFromObj(nameObj, &numBytes);

	classObj = Tcl_NewStringObj(bytes, numBytes);

	numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj));
	Tcl_SetObjLength(classObj, numBytes);
    }

3348
3349
3350
3351
3352
3353
3354




3355
3356
3357
3358
3359
3360
3361
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466







+
+
+
+








	TkCreateThreadExitHandler(DeleteWindowsExitProc, tsdPtr);
    }
  done:
    if (value) {
	Tcl_DecrRefCount(value);
	value = NULL;
    }
    if (appNameObj) {
	Tcl_DecrRefCount(appNameObj);
	appNameObj = NULL;
    }
    return code;
}

/*
 *----------------------------------------------------------------------
 *
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
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,
	Ttk_ElementSpec *elementSpec,
	void *clientData)
}

declare 6 {
    Ttk_ElementClass *Ttk_RegisterElement(
	Tcl_Interp *interp,
	Ttk_Theme theme,
	const char *elementName,
	const Ttk_ElementSpec *elementSpec,
	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
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)
    	Ttk_StateTable map[], Ttk_State state)
}


#
# Low-level geometry utilities.
#
declare 20 {
139
140
141
142
143
144
145
146

147
148
149
150
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 {}} {
declare 40 {
    int Ttk_GetOrientFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient)
}


Changes to generic/ttk/ttkBlink.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
71
72
73

74
75
76
77
78
79
80
30
31
32
33
34
35
36

37
38
39


40
41
42
43
44
45
46
47
48
49
50
51

52
53
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+


-
-












-
+


-
+















-
+







    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)
static void CursorManagerDeleteProc(ClientData clientData, Tcl_Interp *interp)
{
    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);
    CursorManager *cm = Tcl_GetAssocData(interp, cm_key,0);

    if (!cm) {
	cm = (CursorManager *)ckalloc(sizeof(*cm));
	cm = 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;
    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.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
18
19
20
21
22
23
24

25
26
27
28
29
30
31







-







 */
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;

50
51
52
53
54
55
56
57

58
59
60
61
62
63

64
65
66

67
68
69

70
71
72
73

74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89



90
91

92
93
94
95
96
97
98
99


100
101
102
103
104
105
106
49
50
51
52
53
54
55

56
57



58

59
60
61

62
63
64

65
66
67
68

69
70
71
72
73
74
75

76
77
78
79
80
81
82



83
84
85
86

87
88
89
90
91
92
93


94
95
96
97
98
99
100
101
102







-
+

-
-
-

-
+


-
+


-
+



-
+






-
+






-
-
-
+
+
+

-
+






-
-
+
+








typedef struct
{
    WidgetCore	core;
    BasePart	base;
} Base;

static const Tk_OptionSpec BaseOptionSpecs[] =
static 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,
	Tk_Offset(Base,base.textObj), -1,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", "",
	offsetof(Base,base.textVariableObj), TCL_INDEX_NONE,
	Tk_Offset(Base,base.textVariableObj), -1,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	"-1", offsetof(Base,base.underlineObj), TCL_INDEX_NONE,
	"-1", Tk_Offset(Base,base.underlineObj), -1,
	0,0,0 },
    /* SB: OPTION_INT, see <<NOTE-NULLOPTIONS>> */
    {TK_OPTION_STRING, "-width", "width", "Width",
	NULL, offsetof(Base,base.widthObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Base,base.widthObj), -1,
	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_Offset(Base,base.imageObj), -1,
	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 },
	NULL, Tk_Offset(Base,base.compoundObj), -1,
	TK_OPTION_NULL_OK, ttkCompoundStrings,
	GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad",
	NULL, offsetof(Base,base.paddingObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Base,base.paddingObj), -1,
	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 },
	"normal", Tk_Offset(Base,base.stateObj), -1,
	0,0,STATE_CHANGED },

    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * Variable trace procedure for -textvariable option:
 */
119
120
121
122
123
124
125
126



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
115
116
117
118
119
120
121

122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152






153
154
155
156
157
158
159







-
+
+
+


-

















-
-
+
+
+
+
+
+
+


-
-
-
-
-
-







    Tcl_DecrRefCount(basePtr->base.textObj);
    basePtr->base.textObj = newText;

    TtkResizeWidget(&basePtr->core);
}

static void
BaseInitialize(Tcl_Interp *dummy, void *recordPtr)
BaseInitialize(
    TCL_UNUSED(Tcl_Interp *),
    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)
    void *clientData,
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    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;
199
200
201
202
203
204
205
206




207
208
209
210
211
212
213
214
215
216
217
218
195
196
197
198
199
200
201

202
203
204
205
206
207
208


209
210
211
212
213
214
215







-
+
+
+
+



-
-







	TtkCheckStateOption(&basePtr->core, basePtr->base.stateObj);
    }

    return TCL_OK;
}

static int
BasePostConfigure(Tcl_Interp *dummy, void *recordPtr, int mask)
BasePostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    void *recordPtr,
    TCL_UNUSED(int))
{
    Base *basePtr = (Base *)recordPtr;
    int status = TCL_OK;
    (void)dummy;
    (void)mask;

    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
234
235
236
237
238
239
240

241
242
243

244
245
246

247
248
249

250
251
252

253
254
255

256
257
258


259
260
261


262
263
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288







-
+


-
+


-
+


-
+


-
+


-
+


-
-
+
+

-
-
+
+

-
+















-
+







typedef struct
{
    WidgetCore	core;
    BasePart	base;
    LabelPart	label;
} Label;

static const Tk_OptionSpec LabelOptionSpecs[] =
static Tk_OptionSpec LabelOptionSpecs[] =
{
    {TK_OPTION_BORDER, "-background", "frameColor", "FrameColor",
	NULL, offsetof(Label,label.backgroundObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Label,label.backgroundObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	NULL, offsetof(Label,label.foregroundObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Label,label.foregroundObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	NULL, offsetof(Label,label.fontObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Label,label.fontObj), -1,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	NULL, offsetof(Label,label.borderWidthObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Label,label.borderWidthObj), -1,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	NULL, offsetof(Label,label.reliefObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Label,label.reliefObj), -1,
	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},
	"w", Tk_Offset(Label,label.anchorObj), -1,
	0, 0, GEOMETRY_CHANGED},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	NULL, offsetof(Label, label.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
	"left", Tk_Offset(Label, label.justifyObj), -1,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	NULL, offsetof(Label, label.wrapLengthObj), TCL_INDEX_NONE,
	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 const WidgetSpec LabelWidgetSpec =
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
317
318
319
320
321
322
323

324
325
326

327
328


329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+


-
+

-
-
+
+
















-
+







    BasePart	base;
    ButtonPart	button;
} Button;

/*
 * Option specifications:
 */
static const Tk_OptionSpec ButtonOptionSpecs[] =
static Tk_OptionSpec ButtonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Button, button.commandObj), TCL_INDEX_NONE, 0,0,0},
	"", Tk_Offset(Button, button.commandObj), -1, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
	"normal", offsetof(Button, button.defaultStateObj), TCL_INDEX_NONE,
	0, (void *)ttkDefaultStrings, DEFAULTSTATE_CHANGED},
	"normal", Tk_Offset(Button, button.defaultStateObj), -1,
	0, 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;
	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);
	}
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394







-
+







    { "invoke",		ButtonInvokeCommand,0 },
    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ButtonWidgetSpec =
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
427
428
429
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 const Tk_OptionSpec CheckbuttonOptionSpecs[] =
static Tk_OptionSpec CheckbuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	NULL, offsetof(Checkbutton, checkbutton.variableObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Checkbutton, checkbutton.variableObj), -1,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "OnValue",
	"1", offsetof(Checkbutton, checkbutton.onValueObj), TCL_INDEX_NONE,
	"1", Tk_Offset(Checkbutton, checkbutton.onValueObj), -1,
	0,0,0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "OffValue",
	"0", offsetof(Checkbutton, checkbutton.offValueObj), TCL_INDEX_NONE,
	"0", Tk_Offset(Checkbutton, checkbutton.offValueObj), -1,
	0,0,0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Checkbutton, checkbutton.commandObj), TCL_INDEX_NONE,
	"", Tk_Offset(Checkbutton, checkbutton.commandObj), -1,
	0,0,0},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

/*
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602







-
+







    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    /* MISSING: select, deselect, toggle */
    { 0,0,0 }
};

static const WidgetSpec CheckbuttonWidgetSpec =
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
635
636
637
638
639
640
641

642
643
644

645
646
647

648
649
650

651
652
653
654
655
656
657
658







-
+


-
+


-
+


-
+







    BasePart base;
    RadiobuttonPart radiobutton;
} Radiobutton;

/*
 * Option specifications:
 */
static const Tk_OptionSpec RadiobuttonOptionSpecs[] =
static Tk_OptionSpec RadiobuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	"::selectedButton", offsetof(Radiobutton, radiobutton.variableObj),TCL_INDEX_NONE,
	"::selectedButton", Tk_Offset(Radiobutton, radiobutton.variableObj),-1,
	0,0,0},
    {TK_OPTION_STRING, "-value", "Value", "Value",
	"1", offsetof(Radiobutton, radiobutton.valueObj), TCL_INDEX_NONE,
	"1", Tk_Offset(Radiobutton, radiobutton.valueObj), -1,
	0,0,0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Radiobutton, radiobutton.commandObj), TCL_INDEX_NONE,
	"", Tk_Offset(Radiobutton, radiobutton.commandObj), -1,
	0,0,0},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(BaseOptionSpecs)
};

/*
767
768
769
770
771
772
773
774

775
776
777
778
779
780
781
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778







-
+







    { "instate",	TtkWidgetInstateCommand,0 },
    { "state",  	TtkWidgetStateCommand,0 },
    { "identify",	TtkWidgetIdentifyCommand,0 },
    /* MISSING: select, deselect */
    { 0,0,0 }
};

static const WidgetSpec RadiobuttonWidgetSpec =
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
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 const Tk_OptionSpec MenubuttonOptionSpecs[] =
static Tk_OptionSpec MenubuttonOptionSpecs[] =
{
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	"", offsetof(Menubutton, menubutton.menuObj), TCL_INDEX_NONE, 0,0,0},
	"", Tk_Offset(Menubutton, menubutton.menuObj), -1, 0,0,0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	"below", offsetof(Menubutton, menubutton.directionObj), TCL_INDEX_NONE,
	0, (void *)directionStrings, GEOMETRY_CHANGED},
	"below", Tk_Offset(Menubutton, menubutton.directionObj), -1,
	0, 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 =
static WidgetSpec MenubuttonWidgetSpec =
{
    "TMenubutton",		/* className */
    sizeof(Menubutton), 	/* recordSize */
    MenubuttonOptionSpecs, 	/* optionSpecs */
    MenubuttonCommands,  	/* subcommands */
    BaseInitialize,     	/* initializeProc */
    BaseCleanup,		/* cleanupProc */
862
863
864
865
866
867
868
869
870


871
872
873
874
875
876
877
859
860
861
862
863
864
865


866
867
868
869
870
871
872
873
874







-
-
+
+







	        TTK_NODE("Menubutton.label", TTK_PACK_LEFT))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkButton_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkButton_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TLabel", LabelLayout);
    Ttk_RegisterLayout(theme, "TButton", ButtonLayout);
    Ttk_RegisterLayout(theme, "TCheckbutton", CheckbuttonLayout);
    Ttk_RegisterLayout(theme, "TRadiobutton", RadiobuttonLayout);
Changes to generic/ttk/ttkCache.c.
26
27
28
29
30
31
32




33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







+
+
+
+


















-
+







 *
 * @@@ Colormap flashing on PseudoColor visuals is still possible,
 * but this will be a transient effect.
 */

#include "tkInt.h"
#include "ttkTheme.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

struct Ttk_ResourceCache_ {
    Tcl_Interp	  *interp;	/* Interpreter for error reporting */
    Tk_Window	  tkwin;	/* Cache window. */
    Tcl_HashTable fontTable;	/* Entries: Tcl_Obj* holding FontObjs */
    Tcl_HashTable colorTable;	/* Entries: Tcl_Obj* holding ColorObjs */
    Tcl_HashTable borderTable;	/* Entries: Tcl_Obj* holding BorderObjs */
    Tcl_HashTable imageTable;	/* Entries: Tk_Images */

    Tcl_HashTable namedColors;	/* Entries: RGB values as Tcl_StringObjs */
};

/*
 * Ttk_CreateResourceCache --
 * 	Initialize a new resource cache.
 */
Ttk_ResourceCache Ttk_CreateResourceCache(Tcl_Interp *interp)
{
    Ttk_ResourceCache cache = (Ttk_ResourceCache)ckalloc(sizeof(*cache));
    Ttk_ResourceCache cache = ckalloc(sizeof(*cache));

    cache->tkwin = NULL;	/* initialized later */
    cache->interp = interp;
    Tcl_InitHashTable(&cache->fontTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&cache->colorTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&cache->borderTable, TCL_STRING_KEYS);
    Tcl_InitHashTable(&cache->imageTable, TCL_STRING_KEYS);
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+














-
+














-
+














-
+







    Tcl_HashEntry *entryPtr;

    /*
     * Free fonts:
     */
    entryPtr = Tcl_FirstHashEntry(&cache->fontTable, &search);
    while (entryPtr != NULL) {
	Tcl_Obj *fontObj = (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
	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_Obj *)Tcl_GetHashValue(entryPtr);
	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_Obj *)Tcl_GetHashValue(entryPtr);
	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 = (Tk_Image)Tcl_GetHashValue(entryPtr);
	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
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182







-
+














-
+







    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_Obj *colorNameObj = 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;
    Ttk_ResourceCache cache = clientData;

    if (eventPtr->type != DestroyNotify) {
	return;
    }
    Tk_DeleteEventHandler(cache->tkwin, StructureNotifyMask,
	    CacheWinEventHandler, clientData);
    Ttk_ClearCache(cache);
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245










246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
209
210
211
212
213
214
215

216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+






-
+

















-
+








+
+
+
+
+
+
+
+
+
+














-
+







    XColor *colorPtr)
{
    int newEntry;
    Tcl_HashEntry *entryPtr;
    char nameBuf[14];
    Tcl_Obj *colorNameObj;

    sprintf(nameBuf, "#%04X%04X%04X",
    snprintf(nameBuf, sizeof(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_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_Obj *)Tcl_GetHashValue(entryPtr);
    	objPtr = Tcl_GetHashValue(entryPtr);
    }
    return objPtr;
}

/*
 * Template for allocation routines:
 */
typedef void *(*Allocator)(Tcl_Interp *, Tk_Window, Tcl_Obj *);

static void *AllocFont(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) {
	return Tk_AllocFontFromObj(interp, tkwin, objPtr);
}
static void *AllocColor(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) {
	return Tk_AllocColorFromObj(interp, tkwin, objPtr);
}
static void *AllocBorder(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) {
	return Tk_Alloc3DBorderFromObj(interp, tkwin, objPtr);
}

static Tcl_Obj *Ttk_Use(
    Tcl_Interp *interp,
    Tcl_HashTable *table,
    Allocator allocate,
    Tk_Window tkwin,
    Tcl_Obj *objPtr)
{
    int newEntry;
    Tcl_HashEntry *entryPtr =
	Tcl_CreateHashEntry(table,Tcl_GetString(objPtr),&newEntry);
    Tcl_Obj *cacheObj;

    if (!newEntry) {
	return (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
	return Tcl_GetHashValue(entryPtr);
    }

    cacheObj = Tcl_DuplicateObj(objPtr);
    Tcl_IncrRefCount(cacheObj);

    if (allocate(interp, tkwin, cacheObj)) {
	Tcl_SetHashValue(entryPtr, cacheObj);
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317

318
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330

331
332

333








334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363







-
+











-
+












-
+






-
+

-
+
-
-
-
-
-
-
-
-
















-
+













 * Ttk_UseFont --
 * 	Acquire a font from the cache.
 */
Tcl_Obj *Ttk_UseFont(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->fontTable,(Allocator)Tk_AllocFontFromObj, tkwin, objPtr);
	&cache->fontTable, AllocFont, tkwin, objPtr);
}

/*
 * Ttk_UseColor --
 * 	Acquire a color from the cache.
 */
Tcl_Obj *Ttk_UseColor(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    objPtr = CheckNamedColor(cache, objPtr);
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->colorTable,(Allocator)Tk_AllocColorFromObj, tkwin, objPtr);
	&cache->colorTable, AllocColor, tkwin, objPtr);
}

/*
 * Ttk_UseBorder --
 * 	Acquire a Tk_3DBorder from the cache.
 */
Tcl_Obj *Ttk_UseBorder(
    Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
{
    objPtr = CheckNamedColor(cache, objPtr);
    InitCacheWindow(cache, tkwin);
    return Ttk_Use(cache->interp,
	&cache->borderTable,(Allocator)Tk_Alloc3DBorderFromObj, tkwin, objPtr);
	&cache->borderTable, AllocBorder, tkwin, objPtr);
}

/* NullImageChanged --
 * 	Tk_ImageChangedProc for Ttk_UseImage
 */

static void NullImageChanged(ClientData dummy,
static void NullImageChanged(ClientData clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{ /* No-op */
{ /* 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);
	return 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*/
Changes to generic/ttk/ttkClamTheme.c.
9
10
11
12
13
14
15
16

17
18

19
20
21
22
23
24
25
9
10
11
12
13
14
15

16
17

18
19
20
21
22
23
24
25







-
+

-
+








/*
 * 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
  #define WIN32_XDRAWLINE_HACK 1
#else
#	define WIN32_XDRAWLINE_HACK 0
  #define WIN32_XDRAWLINE_HACK 0
#endif

#define STR(x) StR(x)
#define StR(x) #x

#define SCROLLBAR_THICKNESS 14

63
64
65
66
67
68
69
70
71
72
73




74
75
76
77
78
79
80


81
82
83
84
85
86
87


88
89
90
91
92
93
94
63
64
65
66
67
68
69




70
71
72
73
74
75
76
77
78


79
80
81
82
83
84
85


86
87
88
89
90
91
92
93
94







-
-
-
-
+
+
+
+





-
-
+
+





-
-
+
+







    int y1 = b.y, y2 = b.y + b.height - 1;
    const int w = WIN32_XDRAWLINE_HACK;
    GC gc;

    if (   outerColorObj
	&& (gc=Ttk_GCForColor(tkwin,outerColorObj,d)))
    {
	XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1); /* N */
	XDrawLine(display,d,gc, x1+1,y2, x2-1+w,y2); /* S */
	XDrawLine(display,d,gc, x1,y1+1, x1,y2-1+w); /* E */
	XDrawLine(display,d,gc, x2,y1+1, x2,y2-1+w); /* W */
	XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1);		/* N */
	XDrawLine(display,d,gc, x1+1,y2, x2-1+w,y2);		/* S */
	XDrawLine(display,d,gc, x1,y1+1, x1,y2-1+w);		/* W */
	XDrawLine(display,d,gc, x2,y1+1, x2,y2-1+w);		/* E */
    }

    if (   upperColorObj
	&& (gc=Ttk_GCForColor(tkwin,upperColorObj,d)))
    {
	XDrawLine(display,d,gc, x1+1,y1+1, x2-1+w,y1+1); /* N */
	XDrawLine(display,d,gc, x1+1,y1+1, x1+1,y2-1);   /* E */
	XDrawLine(display,d,gc, x1+1,y1+1, x2-1+w,y1+1);	/* N */
	XDrawLine(display,d,gc, x1+1,y1+1, x1+1,y2-1);		/* W */
    }

    if (   lowerColorObj
	&& (gc=Ttk_GCForColor(tkwin,lowerColorObj,d)))
    {
	XDrawLine(display,d,gc, x2-1,y2-1, x1+1-w,y2-1); /* S */
	XDrawLine(display,d,gc, x2-1,y2-1, x2-1,y1+1-w); /* W */
	XDrawLine(display,d,gc, x2-1,y2-1, x1+1-w,y2-1);	/* S */
	XDrawLine(display,d,gc, x2-1,y2-1, x2-1,y1+1-w);	/* E */
    }
}

static GC BackgroundGC(Tk_Window tkwin, Tcl_Obj *backgroundObj)
{
    Tk_3DBorder bd = Tk_Get3DBorderFromObj(tkwin, backgroundObj);
    return Tk_3DBorderGC(tkwin, bd, TK_3D_FLAT_GC);
102
103
104
105
106
107
108
109

110
111

112
113

114
115

116
117

118
119

120
121
122
123
124
125
126
127
128
129
130
131

132
133





134
135
136
137
138
139
140
141
142
143
144
145
146

147
148





149
150
151
152
153
154
155
156
157
158
159
160
161
162
102
103
104
105
106
107
108

109
110

111
112

113
114

115
116

117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132


133
134
135
136
137
138
139
140



141
142
143
144
145
146
147
148


149
150
151
152
153
154
155
156
157
158


159
160
161
162
163
164
165







-
+

-
+

-
+

-
+

-
+

-
+












+
-
-
+
+
+
+
+



-
-
-







+
-
-
+
+
+
+
+





-
-







    Tcl_Obj 	*borderColorObj;
    Tcl_Obj 	*lightColorObj;
    Tcl_Obj 	*darkColorObj;
    Tcl_Obj 	*reliefObj;
    Tcl_Obj 	*borderWidthObj;	/* See <<NOTE-BORDERWIDTH>> */
} BorderElement;

static const Ttk_ElementOptionSpec BorderElementOptions[] = {
static Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(BorderElement,borderColorObj), DARKEST_COLOR },
	Tk_Offset(BorderElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(BorderElement,lightColorObj), LIGHT_COLOR },
	Tk_Offset(BorderElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(BorderElement,darkColorObj), DARK_COLOR },
	Tk_Offset(BorderElement,darkColorObj), DARK_COLOR },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(BorderElement,reliefObj), "flat" },
	Tk_Offset(BorderElement,reliefObj), "flat" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(BorderElement,borderWidthObj), "2" },
	Tk_Offset(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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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) {
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207

208
209

210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226







227
228
229
230

231
232





233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295

296
297

298
299

300
301

302
303

304
305

306
307

308
309
310
311
312
313



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358


359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203

204
205
206

207
208

209
210

211


212

213
214
215
216
217









218
219
220
221
222
223
224
225
226
227
228
229


230
231
232
233
234
235
236
237
238
239
240


241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

295
296

297
298

299
300

301
302

303
304

305
306

307
308
309
310
311


312
313
314
315
316
317
318


319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354


355
356
357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373







-
+














-



-
+

-
+

-
+
-
-

-
+




-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+




+
-
-
+
+
+
+
+






-
-






-
+













-
+












-
+




















-
+

-
+

-
+

-
+

-
+

-
+

-
+




-
-
+
+
+




-
-








-
+








-



















-
-
+
+










-







	    outer = upper = lower = border->borderColorObj;
	    break;
    }

    DrawSmoothBorder(tkwin, d, b, outer, upper, lower);
}

static const Ttk_ElementSpec BorderElementSpec = {
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 const Ttk_ElementOptionSpec FieldElementOptions[] = {
static Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(FieldElement,borderColorObj), DARKEST_COLOR },
	Tk_Offset(FieldElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(FieldElement,lightColorObj), LIGHT_COLOR },
	Tk_Offset(FieldElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(FieldElement,darkColorObj), DARK_COLOR },
    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,backgroundObj), "white" },
	Tk_Offset(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;

    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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)
    Drawable d, Ttk_Box b, Ttk_State 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 = {
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 const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-indicatorsize", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,sizeObj), "10" },
	Tk_Offset(IndicatorElement,sizeObj), "10" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "1" },
	Tk_Offset(IndicatorElement,marginObj), "1" },
    { "-indicatorbackground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,backgroundObj), "white" },
	Tk_Offset(IndicatorElement,backgroundObj), "white" },
    { "-indicatorforeground", TK_OPTION_COLOR,
	offsetof(IndicatorElement,foregroundObj), "black" },
	Tk_Offset(IndicatorElement,foregroundObj), "black" },
    { "-upperbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,upperColorObj), DARKEST_COLOR },
	Tk_Offset(IndicatorElement,upperColorObj), DARKEST_COLOR },
    { "-lowerbordercolor", TK_OPTION_COLOR,
	offsetof(IndicatorElement,lowerColorObj), DARK_COLOR },
	Tk_Offset(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)
    TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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,
    TCL_UNUSED(void *), 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)
    TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State 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*/
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425

426
427
428

429
430
431

432
433
434
435
436
437
438



439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420
421

422
423
424

425
426
427

428
429
430
431
432
433


434
435
436
437
438
439
440


441
442
443
444
445
446
447
448
449


450
451
452
453
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







-
+







-
+















-
+


-
+


-
+


-
+





-
-
+
+
+




-
-









-
-
+
+
+






-
-








-
+













+
+
+
+







-
+

-
+

-
-
-
+
+
+





-
+
+

-
+


-
-

-
-
+
+








-
+
+


-
+





-

-
+

-
+
















-
+







	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 = {
static Ttk_ElementSpec RadioIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    IndicatorElementSize,
    RadioIndicatorElementDraw
};

static const Ttk_ElementSpec CheckIndicatorElementSpec = {
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 const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] =
static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] =
{
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,sizeObj),
	Tk_Offset(MenuIndicatorElement,sizeObj),
	STR(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(MenuIndicatorElement,colorObj),
	Tk_Offset(MenuIndicatorElement,colorObj),
	"black" },
    { "-arrowpadding",TK_OPTION_STRING,
	offsetof(MenuIndicatorElement,paddingObj),
	Tk_Offset(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)
    TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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)
    TCL_UNUSED(void *), void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_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 =
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 const Ttk_ElementOptionSpec GripElementOptions[] = {
static Ttk_ElementOptionSpec GripElementOptions[] = {
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(GripElement,lightColorObj), LIGHT_COLOR },
	Tk_Offset(GripElement,lightColorObj), LIGHT_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(GripElement,borderColorObj), DARKEST_COLOR },
    { "-gripcount", TK_OPTION_INT,
	offsetof(GripElement,gripCountObj), "5" },
	Tk_Offset(GripElement,borderColorObj), DARKEST_COLOR },
    { "-gripcount", TK_OPTION_PIXELS,
	Tk_Offset(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)
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
    GripElement *grip = (GripElement *)elementRecord;
    int gripCount = 0;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, grip->gripCountObj, &gripCount);
    if (orient == TTK_ORIENT_HORIZONTAL) {
    Tk_GetPixelsFromObj(NULL, tkwin, 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)
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    const int w = WIN32_XDRAWLINE_HACK;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
    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);
    Tk_GetPixelsFromObj(NULL, tkwin, grip->gripCountObj, &gripCount);

    if (orient == TTK_ORIENT_HORIZONTAL) {
    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 const Ttk_ElementSpec GripElementSpec = {
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
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







-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
-
-
-
-
+
+
+
+
+




+
-
-
+
+
+
+
+




-
-





-
+








+
-
-
+
+
+
+
+



-
-
-

-
+




+
-
-
+
+
+
+
+



-
+



-
-










-
-
+
+







    Tcl_Obj 	*darkColorObj;
    Tcl_Obj 	*arrowColorObj;
    Tcl_Obj 	*arrowSizeObj;
    Tcl_Obj 	*gripCountObj;
    Tcl_Obj 	*sliderlengthObj;
} ScrollbarElement;

static const Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(ScrollbarElement, orientObj), "horizontal" },
	Tk_Offset(ScrollbarElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(ScrollbarElement,backgroundObj), FRAME_COLOR },
	Tk_Offset(ScrollbarElement,backgroundObj), FRAME_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,borderColorObj), DARKEST_COLOR },
	Tk_Offset(ScrollbarElement,borderColorObj), DARKEST_COLOR },
    { "-troughcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,troughColorObj), DARKER_COLOR },
	Tk_Offset(ScrollbarElement,troughColorObj), DARKER_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,lightColorObj), LIGHT_COLOR },
	Tk_Offset(ScrollbarElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,darkColorObj), DARK_COLOR },
	Tk_Offset(ScrollbarElement,darkColorObj), DARK_COLOR },
    { "-arrowcolor", TK_OPTION_COLOR,
	offsetof(ScrollbarElement,arrowColorObj), "#000000" },
	Tk_Offset(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" },
	Tk_Offset(ScrollbarElement,arrowSizeObj), STR(SCROLLBAR_THICKNESS) },
    { "-gripcount", TK_OPTION_PIXELS,
	Tk_Offset(ScrollbarElement,gripCountObj), "5" },
    { "-sliderlength", TK_OPTION_PIXELS,
	Tk_Offset(ScrollbarElement,sliderlengthObj), "30" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
static Ttk_ElementSpec TroughElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TtkNullElementSize,
    TroughElementDraw
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int size = SCROLLBAR_THICKNESS;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &size);
    Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
    *widthPtr = *heightPtr = size;
}

static void ThumbElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int gripCount = 0;
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    int 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);
    Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, 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;
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
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







-
+











+
-
-
+
+
+
+
+



-
+
-
-


-
-
+
+








-
-
+
+
-
-
+







	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 = {
static Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/*------------------------------------------------------------------------
 * +++ Slider element.
 */
static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    int length, thickness;
    Ttk_Orient orient;
    int orient;
    (void)dummy;
    (void)paddingPtr;

    length = thickness = SCROLLBAR_THICKNESS;
    TtkGetOrientFromObj(NULL, sb->orientObj, &orient);
    Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &thickness);
    Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient);
    Tk_GetPixelsFromObj(NULL, tkwin, 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 = {
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
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
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







+
-
-
+
+
+
+
+


-
-











-
+







-



+
+

-
-
+
+
+


+
+

-
-
-

-
-
+
+
+
+
+
+
+
+
+
+




-
+
+

-

+
+
+
-
+
-
-








-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+















-
+

-
+

-
+

-
+

-
+




+
+
-
-
+
+
+
+

+
+

-
+
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
+
+
+
+
+

+
+
+



-
-
+


-
+
+
+
+


-
+


+
+
+
-
-
-
+
+
+

-
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+

+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









+
-
-
+
+
+
+
+


-
-
-
-
-





+
-
-
+
+
+
+
+




-
-







-
+







	    widthPtr, heightPtr, paddingPtr);
    *paddingPtr = Ttk_UniformPadding(2);
    *widthPtr += 4;
    *heightPtr += 4;
}

static void PbarElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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 *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    ArrowDirection direction = *(ArrowDirection*)clientData;
    Ttk_Padding padding = Ttk_UniformPadding(3);
    int size = SCROLLBAR_THICKNESS;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    Tcl_GetIntFromObj(NULL, sb->arrowSizeObj, &size);
    *widthPtr = *heightPtr = size;
    Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
    if (*widthPtr < *heightPtr) {
	*widthPtr = *heightPtr;
    } else {
	*heightPtr = *widthPtr;
    }
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned state)
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    ArrowDirection direction = *(ArrowDirection*)clientData;
    Ttk_Padding padding = Ttk_UniformPadding(3);
    int cx, cy;
    GC gc = Ttk_GCForColor(tkwin,sb->arrowColorObj, d);
    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_PadBox(b, padding);

    switch (direction) {
	case ARROW_UP:
	case ARROW_DOWN:
	    TtkArrowSize(b.width/2, direction, &cx, &cy);
	    if ((b.height - cy) % 2 == 1) {
		++cy;
	    }
	    break;
	case ARROW_LEFT:
	case ARROW_RIGHT:
	    TtkArrowSize(b.height/2, direction, &cx, &cy);
	    if ((b.width - cx) % 2 == 1) {
		++cx;
	    }
	    break;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);
}

static const Ttk_ElementSpec ArrowElementSpec = {
static Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};

/*
 * Modified arrow element for spinboxes:
 * 	The width and height are different.
 */
static void SpinboxArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ScrollbarElement *sb = (ScrollbarElement *)elementRecord;
    ArrowDirection direction = *(ArrowDirection*)clientData;
    Ttk_Padding padding = Ttk_UniformPadding(3);
    int size = 10;

    Tk_GetPixelsFromObj(NULL, tkwin, sb->arrowSizeObj, &size);
    size -= Ttk_PaddingWidth(padding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(padding);
    *heightPtr += Ttk_PaddingHeight(padding);
}

static Ttk_ElementSpec SpinboxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    SpinboxArrowElementSize,
    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[] = {
static Ttk_ElementOptionSpec NotebookElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(NotebookElement,backgroundObj), FRAME_COLOR },
	Tk_Offset(NotebookElement,backgroundObj), FRAME_COLOR },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,borderColorObj), DARKEST_COLOR },
	Tk_Offset(NotebookElement,borderColorObj), DARKEST_COLOR },
    { "-lightcolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,lightColorObj), LIGHT_COLOR },
	Tk_Offset(NotebookElement,lightColorObj), LIGHT_COLOR },
    { "-darkcolor", TK_OPTION_COLOR,
	offsetof(NotebookElement,darkColorObj), DARK_COLOR },
	Tk_Offset(NotebookElement,darkColorObj), DARK_COLOR },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TabElementSize(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    int borderWidth = 2;
    (void)dummy;

    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    if (mainInfoPtr != NULL) {
    (void)heightPtr;

    paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;
    paddingPtr->bottom = 0;
}

	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    int borderWidth = 2, delta = 0;
    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;
    int x1, y1, x2, y2;
    GC gc;
    const int w = WIN32_XDRAWLINE_HACK;
    (void)dummy;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    if (state & TTK_STATE_SELECTED) {
	dh = borderWidth;
	delta = borderWidth;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
    if (state & TTK_STATE_USER2) {	/* Rightmost tab */
	--b.width;
    }
	    if (state & TTK_STATE_USER2) {		/* rightmost tab */
		--b.width;
	    }

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x+2, b.y+2, b.width-1, b.height-2+dh, borderWidth, TK_RELIEF_FLAT);
	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x;		y1 = b.y;		/* top left */
	    x2 = b.x + b.width; y2 = b.y + b.height-1;	/* bottom right */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1+1, x1, y2+1+w);
	    XDrawLine(display, d, gc, x2, y1+1, x2, y2+1+w);
	    XDrawLine(display, d, gc, x1+1, y1, x2-1+w, y1);

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2+delta+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2-1+w, y1+1);
	    break;

	case TTK_STICK_N:
	    if (state & TTK_STATE_USER2) {		/* rightmost tab */
		--b.width;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y-delta, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x;		y1 = b.y + b.height-1;	/* bottom left */
    x1 = b.x, x2 = b.x + b.width;
    y1 = b.y, y2 = b.y + b.height;
	    x2 = b.x + b.width; y2 = b.y;		/* top right */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1-1, x1, y2-1-w);
	    XDrawLine(display, d, gc, x2, y1-1, x2, y2-1-w);
	    XDrawLine(display, d, gc, x1+1, y1, x2-1+w, y1);

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1-1, x1+1, y2-delta-w);
	    XDrawLine(display, d, gc, x1+1, y1-1, x2-1+w, y1-1);
	    break;

	case TTK_STICK_E:
	    if (state & TTK_STATE_USER2) {		/* bottommost tab */
		--b.height;

    gc=Ttk_GCForColor(tkwin,tab->borderColorObj,d);
    XDrawLine(display,d,gc, x1,y1+1, x1,y2+w);
    XDrawLine(display,d,gc, x2,y1+1, x2,y2+w);
    XDrawLine(display,d,gc, x1+1,y1, x2-1+w,y1);
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x;		  y1 = b.y;		/* top left */
	    x2 = b.x + b.width-1; y2 = b.y + b.height;	/* bottom right */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1+1, x1, y2-1+w);
	    XDrawLine(display, d, gc, x1+1, y1, x2+1+w, y1);
	    XDrawLine(display, d, gc, x1+1, y2, x2+1+w, y2);

    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 =
	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2-1+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2+delta+w, y1+1);
	    break;

	case TTK_STICK_W:
	    if (state & TTK_STATE_USER2) {		/* bottommost tab */
		--b.height;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x-delta, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);

	    x1 = b.x + b.width-1; y1 = b.y;		/* top right */
	    x2 = b.x;		  y2 = b.y + b.height;	/* bottom left */

	    gc = Ttk_GCForColor(tkwin, tab->borderColorObj, d);
	    XDrawLine(display, d, gc, x1, y1+1, x1, y2-1+w);
	    XDrawLine(display, d, gc, x1-1, y1, x2-1-w, y1);
	    XDrawLine(display, d, gc, x1-1, y2, x2-1-w, y2);

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1-1, y1+1, x1-1, y2-1+w);
	    XDrawLine(display, d, gc, x1-1, y1+1, x2-delta-w, y1+1);
	    break;
    }
}

static Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NotebookElement),
    NotebookElementOptions,
    TabElementSize,
    TabElementDraw
};

static void ClientElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 =
static Ttk_ElementSpec ClientElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NotebookElement),
    NotebookElementOptions,
    ClientElementSize,
    ClientElementDraw
};
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+









-
+

-
+







{
    Ttk_Theme theme = Ttk_CreateTheme(interp, "clam", 0);

    if (!theme) {
        return TCL_ERROR;
    }

    Ttk_RegisterElement(interp,
	theme, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "Combobox.field", &ComboboxFieldElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "trough", &TroughElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "uparrow", &ArrowElementSpec, 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, "border",
	    &BorderElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "field",
	    &FieldElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Combobox.field",
	    &ComboboxFieldElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "trough",
	    &TroughElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "thumb",
	    &ThumbElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, &ArrowElements[0]);
    Ttk_RegisterElement(interp, theme, "Spinbox.uparrow",
	    &SpinboxArrowElementSpec, &ArrowElements[0]);
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "Spinbox.downarrow",
	    &SpinboxArrowElementSpec, &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, "Radiobutton.indicator", &RadioIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "Checkbutton.indicator", &CheckIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp,
	theme, "Menubutton.indicator", &MenuIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &CheckIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &RadioIndicatorElementSpec, 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));
	    &GripElementSpec,  &GripClientData[0]);
    Ttk_RegisterElement(interp, theme, "vgrip",
	    &GripElementSpec,  INT2PTR(TTK_ORIENT_VERTICAL));
	    &GripElementSpec,  &GripClientData[1]);

    Ttk_RegisterLayouts(theme, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::clam", TTK_VERSION);

    return TCL_OK;
}
Changes to generic/ttk/ttkClassicTheme.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
15
16
17
18
19
20
21
22
23
24

25
26

27
28

29
30
31
32
33
34
35
36


37
38
39
40
41
42
43
44




45

46
47
48
49
50
51


52
53
54
55
56
57
58
59
60



61
62
63

64
65
66
67
68


69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85







+


-
+

-
+

-
+
+
+




+
-
-
+
+
+
+
+



-
-
-
-

-
+




+
-
-
+
+
+
+
+




-
-
-
+

+
-
+

+
+
+
-
-
+
+
+
+
+
+



-
+







 * +++ Highlight element implementation.
 * 	Draw a solid highlight border to indicate focus.
 */

typedef struct {
    Tcl_Obj	*highlightColorObj;
    Tcl_Obj	*highlightThicknessObj;
    Tcl_Obj	*defaultStateObj;
} HighlightElement;

static const Ttk_ElementOptionSpec HighlightElementOptions[] = {
static Ttk_ElementOptionSpec HighlightElementOptions[] = {
    { "-highlightcolor",TK_OPTION_COLOR,
	offsetof(HighlightElement,highlightColorObj), DEFAULT_BACKGROUND },
	Tk_Offset(HighlightElement,highlightColorObj), DEFAULT_BACKGROUND },
    { "-highlightthickness",TK_OPTION_PIXELS,
	offsetof(HighlightElement,highlightThicknessObj), "0" },
	Tk_Offset(HighlightElement,highlightThicknessObj), "0" },
    { "-default", TK_OPTION_ANY,
	Tk_Offset(HighlightElement,defaultStateObj), "disabled" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void HighlightElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(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);
    Tk_GetPixelsFromObj(NULL, tkwin, hl->highlightThicknessObj, &highlightThickness);
    *paddingPtr = Ttk_UniformPadding((short)highlightThickness);
}

static void HighlightElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_State))
{
    HighlightElement *hl = (HighlightElement *)elementRecord;
    int highlightThickness = 0;
    XColor *highlightColor = Tk_GetColorFromObj(tkwin, hl->highlightColorObj);
    (void)dummy;
    (void)b;
    (void)state;
    int defaultState = TTK_BUTTON_DEFAULT_DISABLED;

    Tk_GetPixelsFromObj(NULL, tkwin, hl->highlightThicknessObj,
    Tcl_GetIntFromObj(NULL,hl->highlightThicknessObj,&highlightThickness);
	&highlightThickness);
    if (highlightColor && highlightThickness > 0) {
	GC gc;
	Ttk_GetButtonDefaultStateFromObj(NULL, hl->defaultStateObj,
	    &defaultState);
	GC gc = Tk_GCForColor(highlightColor, d);
	Tk_DrawFocusHighlight(tkwin, gc, highlightThickness, d);
	gc = Tk_GCForColor(highlightColor, d);
	if (defaultState == TTK_BUTTON_DEFAULT_NORMAL) {
	    TkDrawInsetFocusHighlight(tkwin, gc, highlightThickness, d, 5);
	} else {
	    Tk_DrawFocusHighlight(tkwin, gc, highlightThickness, d);
	}
    }
}

static const Ttk_ElementSpec HighlightElementSpec =
static Ttk_ElementSpec HighlightElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(HighlightElement),
    HighlightElementOptions,
    HighlightElementSize,
    HighlightElementDraw
};
84
85
86
87
88
89
90
91

92
93
94

95
96

97
98

99
100

101
102
103
104

105
106





107
108
109

110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132





133
134
135
136
137

138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

162
163
164
165


166
167
168
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210

211
212

213
214

215
216

217
218

219
220
221
222

223
224





225
226
227
228
229
230
231
232
233
234
235
236
237


238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
97
98
99
100
101
102
103

104
105
106

107
108

109
110

111
112

113
114
115
116
117
118


119
120
121
122
123
124
125

126
127




128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144


145
146
147
148
149
150
151
152
153

154
155


156
157
158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177
178


179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227

228
229

230
231

232
233

234
235
236
237
238
239


240
241
242
243
244
245
246
247


248
249
250
251
252
253
254

255
256
257

258
259
260
261
262
263
264

265
266
267

268
269
270
271
272
273
274







-
+


-
+

-
+

-
+

-
+




+
-
-
+
+
+
+
+


-
+

-
-
-
-

-
+














+
-
-
+
+
+
+
+




-
+

-
-





-
+














-
+


-
-
+
+



-
+
















-
+















+








-
+

-
+

-
+

-
+

-
+




+
-
-
+
+
+
+
+



-
-







-
+
+

-
+






-



-







typedef struct {
    Tcl_Obj	*borderObj;
    Tcl_Obj	*borderWidthObj;
    Tcl_Obj	*reliefObj;
    Tcl_Obj	*defaultStateObj;
} ButtonBorderElement;

static const Ttk_ElementOptionSpec ButtonBorderElementOptions[] =
static Ttk_ElementOptionSpec ButtonBorderElementOptions[] =
{
    { "-background", TK_OPTION_BORDER,
	offsetof(ButtonBorderElement,borderObj), DEFAULT_BACKGROUND },
	Tk_Offset(ButtonBorderElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ButtonBorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
	Tk_Offset(ButtonBorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ButtonBorderElement,reliefObj), "flat" },
	Tk_Offset(ButtonBorderElement,reliefObj), "flat" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
	Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ButtonBorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int borderWidth = 0;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, 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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 1, relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int 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_GetPixelsFromObj(NULL, tkwin, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    /*
     * Default ring:
     */
    switch (defaultState)
    {
	case TTK_BUTTON_DEFAULT_DISABLED :
	    break;
	case TTK_BUTTON_DEFAULT_NORMAL :
	    inset += 5;
	    break;
	case TTK_BUTTON_DEFAULT_ACTIVE :
            Tk_Draw3DRectangle(tkwin, d, border,
	    Tk_Draw3DRectangle(tkwin, d, border,
		b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
		2, TK_RELIEF_FLAT);
            inset += 2;
            Tk_Draw3DRectangle(tkwin, d, border,
	    inset += 2;
	    Tk_Draw3DRectangle(tkwin, d, border,
		b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
		1, TK_RELIEF_SUNKEN);
	    ++inset;
            Tk_Draw3DRectangle(tkwin, d, border,
	    Tk_Draw3DRectangle(tkwin, d, border,
		b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
		2, TK_RELIEF_FLAT);
	    inset += 2;
	    break;
    }

    /*
     * 3-D border:
     */
    if (border && borderWidth > 0) {
	Tk_Draw3DRectangle(tkwin, d, border,
	    b.x+inset, b.y+inset, b.width - 2*inset, b.height - 2*inset,
	    borderWidth,relief);
    }
}

static const Ttk_ElementSpec ButtonBorderElementSpec =
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 const Ttk_ElementOptionSpec ArrowElementOptions[] =
static Ttk_ElementOptionSpec ArrowElementOptions[] =
{
    { "-arrowsize", TK_OPTION_PIXELS, offsetof(ArrowElement,sizeObj),
    { "-arrowsize", TK_OPTION_PIXELS, Tk_Offset(ArrowElement,sizeObj),
	DEFAULT_ARROW_SIZE },
    { "-background", TK_OPTION_BORDER, offsetof(ArrowElement,borderObj),
    { "-background", TK_OPTION_BORDER, Tk_Offset(ArrowElement,borderObj),
    	DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(ArrowElement,borderWidthObj),
    { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(ArrowElement,borderWidthObj),
    	DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF, offsetof(ArrowElement,reliefObj),"raised" },
    { "-relief", TK_OPTION_RELIEF, Tk_Offset(ArrowElement,reliefObj),"raised" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ArrowElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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)
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    int direction = *(int *)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;
     * @@@ need to take a look at Tk_Fill3DPolygon and X11 to find the
     * @@@ exact rules.
     */
    switch (direction)
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308







-
+







	    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 =
static Ttk_ElementSpec ArrowElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};
300
301
302
303
304
305
306




307
308
309
310
311
312
313
314
315
316
317

318
319

320
321

322
323

324
325

326
327

328
329

330
331
332
333
334
335


336
337
338
339

340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358


359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

338
339

340
341

342
343

344
345

346
347

348
349

350
351
352
353
354
355

356
357
358
359
360

361


362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385

386
387

388
389
390
391
392
393
394







+
+
+
+










-
+

-
+

-
+

-
+

-
+

-
+

-
+





-
+
+



-
+
-
-








-
+







-
+
+






-
+

-







 *
 * 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 const Ttk_ElementOptionSpec SashOptions[] = {
static Ttk_ElementOptionSpec SashOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(SashElement,borderObj), DEFAULT_BACKGROUND },
	Tk_Offset(SashElement,borderObj), DEFAULT_BACKGROUND },
    { "-sashrelief", TK_OPTION_RELIEF,
	offsetof(SashElement,sashReliefObj), "sunken" },
	Tk_Offset(SashElement,sashReliefObj), "sunken" },
    { "-sashthickness", TK_OPTION_PIXELS,
	offsetof(SashElement,sashThicknessObj), "6" },
	Tk_Offset(SashElement,sashThicknessObj), "6" },
    { "-sashpad", TK_OPTION_PIXELS,
	offsetof(SashElement,sashPadObj), "2" },
	Tk_Offset(SashElement,sashPadObj), "2" },
    { "-handlesize", TK_OPTION_PIXELS,
	offsetof(SashElement,handleSizeObj), "8" },
	Tk_Offset(SashElement,handleSizeObj), "8" },
    { "-handlepad", TK_OPTION_PIXELS,
	offsetof(SashElement,handlePadObj), "8" },
	Tk_Offset(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)
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SashElement *sash = (SashElement *)elementRecord;
    int sashPad = 2, sashThickness = 6, handleSize = 8;
    Ttk_Orient orient = (Ttk_Orient)PTR2INT(clientData);
    int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
    (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)
    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)
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_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);
    int horizontal = *((Ttk_Orient*)clientData) == TTK_ORIENT_HORIZONTAL;
    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:
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434

435
436

437
438
439
440

441
442
443


444
445
446
447

448
449
450


451
452
453
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
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424
425

426
427
428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

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







-
+












-
+











-
+















-
+

-
+



-
+

-
-
+
+



-
+

-
-
+
+



-
+


-
+




-
+

-
+

+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
-





+
-
+

















-
+

-
+

-
+

-
+

-
+


-
+

-
+












	default:
	    gc1 = gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
	    break;
    }

    /* Draw sash line:
     */
    if (orient == TTK_ORIENT_HORIZONTAL) {
    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 (orient == TTK_ORIENT_HORIZONTAL) {
	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 const Ttk_ElementSpec SashElementSpec = {
static Ttk_ElementSpec SashElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SashElement),
    SashOptions,
    SashElementSize,
    SashElementDraw
};

/*------------------------------------------------------------------------
 * +++ Widget layouts.
 */

TTK_BEGIN_LAYOUT_TABLE(LayoutTable)

TTK_LAYOUT("TButton",
    TTK_GROUP("Button.highlight", TTK_FILL_BOTH,
        TTK_GROUP("Button.border", TTK_FILL_BOTH|TTK_BORDER,
	TTK_GROUP("Button.border", TTK_FILL_BOTH|TTK_BORDER,
	    TTK_GROUP("Button.padding", TTK_FILL_BOTH,
	        TTK_NODE("Button.label", TTK_FILL_BOTH)))))
		TTK_NODE("Button.label", TTK_FILL_BOTH)))))

TTK_LAYOUT("TCheckbutton",
    TTK_GROUP("Checkbutton.highlight", TTK_FILL_BOTH,
        TTK_GROUP("Checkbutton.border", TTK_FILL_BOTH,
	TTK_GROUP("Checkbutton.border", TTK_FILL_BOTH,
	    TTK_GROUP("Checkbutton.padding", TTK_FILL_BOTH,
	        TTK_NODE("Checkbutton.indicator", TTK_PACK_LEFT)
	        TTK_NODE("Checkbutton.label", TTK_PACK_LEFT|TTK_FILL_BOTH)))))
		TTK_NODE("Checkbutton.indicator", TTK_PACK_LEFT)
		TTK_NODE("Checkbutton.label", TTK_PACK_LEFT|TTK_FILL_BOTH)))))

TTK_LAYOUT("TRadiobutton",
    TTK_GROUP("Radiobutton.highlight", TTK_FILL_BOTH,
        TTK_GROUP("Radiobutton.border", TTK_FILL_BOTH,
	TTK_GROUP("Radiobutton.border", TTK_FILL_BOTH,
	    TTK_GROUP("Radiobutton.padding", TTK_FILL_BOTH,
	        TTK_NODE("Radiobutton.indicator", TTK_PACK_LEFT)
	        TTK_NODE("Radiobutton.label", TTK_PACK_LEFT|TTK_FILL_BOTH)))))
		TTK_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_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)))))
		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.field", TTK_FILL_BOTH|TTK_BORDER,
	    TTK_GROUP("Entry.padding", TTK_FILL_BOTH,
	        TTK_NODE("Entry.textarea", TTK_FILL_BOTH)))))
		TTK_NODE("Entry.textarea", TTK_FILL_BOTH)))))

/* "classic" combobox, includes highlight border */
TTK_LAYOUT("TCombobox",
    TTK_GROUP("Combobox.highlight", TTK_FILL_BOTH,
	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)))))
/* Notebook tabs -- omit focus ring */
TTK_LAYOUT("Tab",
    TTK_GROUP("Notebook.tab", TTK_FILL_BOTH,
	TTK_GROUP("Notebook.padding", TTK_FILL_BOTH,
	    TTK_NODE("Notebook.label", TTK_FILL_BOTH))))

/* "classic" spinbox, includes highlight border */
TTK_LAYOUT("TSpinbox",
    TTK_GROUP("Spinbox.highlight", TTK_FILL_BOTH,
	TTK_GROUP("Spinbox.field", TTK_FILL_BOTH|TTK_FILL_X,
	    TTK_GROUP("null", TTK_PACK_RIGHT,
		TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP|TTK_STICK_E)
		TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM|TTK_STICK_E))
	    TTK_GROUP("Spinbox.padding", TTK_FILL_BOTH,
		TTK_NODE("Spinbox.textarea", TTK_FILL_BOTH)))))

/* "classic" scale, includes highlight border */
TTK_LAYOUT("Vertical.TScale",
    TTK_GROUP("Vertical.Scale.highlight", TTK_FILL_BOTH,
	TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH,
	    TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP))))

TTK_LAYOUT("Horizontal.TScale",
    TTK_GROUP("Horizontal.Scale.highlight", TTK_FILL_BOTH,
	TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
	    TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT))))

/* put highlight border around treeview */
TTK_LAYOUT("Treeview",
    TTK_GROUP("Treeview.highlight", TTK_FILL_BOTH,
	TTK_GROUP("Treeview.field", TTK_FILL_BOTH|TTK_BORDER,
	    TTK_GROUP("Treeview.padding", TTK_FILL_BOTH,
		TTK_NODE("Treeview.treearea", TTK_FILL_BOTH)))))

TTK_END_LAYOUT_TABLE

/* POSSIBLY: include Scale layouts w/focus border
 */

/*------------------------------------------------------------------------
 * TtkClassicTheme_Init --
 * 	Install classic theme.
 */

MODULE_SCOPE int
MODULE_SCOPE int TtkClassicTheme_Init(Tcl_Interp *interp)
TtkClassicTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_CreateTheme(interp, "classic", NULL);

    if (!theme) {
	return TCL_ERROR;
    }

    /*
     * Register elements:
     */
    Ttk_RegisterElement(interp, theme, "highlight",
	    &HighlightElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Button.border",
	    &ButtonBorderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
	    &ArrowElementSpec, &ArrowElements[0]);
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
	    &ArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
	    &ArrowElementSpec, &ArrowElements[2]);
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
	    &ArrowElementSpec, &ArrowElements[3]);
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
	    &ArrowElementSpec, &ArrowElements[0]);

    Ttk_RegisterElement(interp, theme, "hsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_HORIZONTAL));
	    &SashElementSpec, &SashClientData[0]);
    Ttk_RegisterElement(interp, theme, "vsash",
	    &SashElementSpec, INT2PTR(TTK_ORIENT_VERTICAL));
	    &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.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
12
13
14
15
16
17
18









19
20
21
22
23
24
25







-
-
-
-
-
-
-
-
-







#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

52
53
54
55
56
57
58
59

60
61
62
63
64

65
66
67
68
69
70
71
43
44
45
46
47
48
49

50
51
52
53
54

55
56
57
58
59
60
61
62







-
+




-
+







/* 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,
				Ttk_ElementSpec *elementSpec,
				void *clientData);
/* 6 */
TTKAPI Ttk_ElementClass * Ttk_RegisterElement(Tcl_Interp *interp,
				Ttk_Theme theme, const char *elementName,
				const Ttk_ElementSpec *elementSpec,
				Ttk_ElementSpec *elementSpec,
				void *clientData);
/* 7 */
TTKAPI int		Ttk_RegisterElementFactory(Tcl_Interp *interp,
				const char *name,
				Ttk_ElementFactory factoryProc,
				void *clientData);
/* 8 */
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+







/* 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,
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
126
127
128
129
130
131
132


133
134
135
136
137
138
139
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 */
TTK_DEPRECATED("")
int			Ttk_GetOrientFromObj(Tcl_Interp *interp,
TTKAPI 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_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) (const Ttk_StateTable *map, Ttk_State state); /* 14 */
    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
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);
    TCL_DEPRECATED_API("") int (*ttk_GetOrientFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *orient); /* 40 */
    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.
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57







-
+









-
+







 * 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] = {
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 const enum BorderColor thinShadowColors[6][4] = {
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*/
};
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118


119
120
121
122
123
124
125

126
127

128
129

130
131

132
133
134
135
136
137
138
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128

129
130

131
132

133
134
135
136
137
138
139
140







-
+







+
+






-
+

-
+

-
+

-
+







	    DrawCorner(tkwin, d, border, borderGC,
		b.x, b.y, b.width, b.height, 1, thinShadowColors[relief][1]);
	    break;
	case 0:	/* no border -- do nothing */
	    break;
	default: /* Fall back to Motif-style borders: */
	    Tk_Draw3DRectangle(tkwin, d, border,
		b.x, b.y, b.width, b.height, borderWidth,relief);
		b.x, b.y, b.width, b.height, borderWidth, relief);
	    break;
    }
}

/* Alternate shadow colors for entry fields:
 * NOTE: FLAT color is normally white, and the LITE color is a darker shade.
 */
static int fieldShadowColors[4] = { DARK, BRDR, LITE, FLAT };

static void DrawFieldBorder(
    Tk_Window tkwin, Drawable d, Tk_3DBorder border, XColor *borderColor,
    Ttk_Box b)
{
    GC borderGC = Tk_GCForColor(borderColor, d);
    DrawCorner(tkwin, d, border, borderGC,
	b.x, b.y, b.width, b.height, 0, DARK);
	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, BRDR);
	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, LITE);
	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, FLAT);
	b.x, b.y, b.width, b.height, 1,fieldShadowColors[3]);
    return;
}

/*
 * ArrowPoints --
 * 	Compute points of arrow polygon.
 */
238
239
240
241
242
243
244
245
246


247
248
249
250


251
252

253
254

255
256

257
258
259

260
261





262
263
264
265

266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281

282
283





284
285
286
287
288
289
290

291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322
323
324
325
326
327
328


329
330
331
332


333
334

335




336
337
338
339
340
341
342
343
344
345
346
347
348







349
350
351
352

353
354


355
356
357
358

359
360







361





























362
363
364
365
366
367

















368
369
370
371
372
373
374
240
241
242
243
244
245
246


247
248
249
250


251
252
253

254
255

256
257

258
259
260
261
262


263
264
265
266
267
268
269
270

271




272

273
274
275
276
277
278
279
280
281
282
283
284


285
286
287
288
289
290
291
292
293
294
295

296


297
298
299
300

301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336


337
338
339

340
341
342
343
344
345
346
347
348
349









350
351
352
353
354
355
356
357
358
359
360
361


362
363
364
365
366
367
368


369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405






406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429







-
-
+
+


-
-
+
+

-
+

-
+

-
+



+
-
-
+
+
+
+
+



-
+
-
-
-
-

-
+










+
-
-
+
+
+
+
+






-
+
-
-




-
+
















-
+














+
+


-
-
+
+

-
+

+
+
+
+




-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+




+
-
-
+
+




+
-
-
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    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),
static Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-background", TK_OPTION_BORDER, Tk_Offset(BorderElement,borderObj),
    	DEFAULT_BACKGROUND },
    { "-bordercolor",TK_OPTION_COLOR,
	offsetof(BorderElement,borderColorObj), "black" },
    { "-default", TK_OPTION_ANY, offsetof(BorderElement,defaultStateObj),
	Tk_Offset(BorderElement,borderColorObj), "black" },
    { "-default", TK_OPTION_ANY, Tk_Offset(BorderElement,defaultStateObj),
    	"disabled" },
    { "-borderwidth",TK_OPTION_PIXELS, offsetof(BorderElement,borderWidthObj),
    { "-borderwidth",TK_OPTION_PIXELS, Tk_Offset(BorderElement,borderWidthObj),
    	STRINGIFY(BORDERWIDTH) },
    { "-relief", TK_OPTION_RELIEF, offsetof(BorderElement,reliefObj),
    { "-relief", TK_OPTION_RELIEF, Tk_Offset(BorderElement,reliefObj),
    	"flat" },
        { NULL, TK_OPTION_BOOLEAN, 0, NULL }
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    BorderElement *bd = (BorderElement *)elementRecord;
    int borderWidth = 0;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    (void)dummy;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;

    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, bd->borderWidthObj, &borderWidth);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
	++borderWidth;
    }

    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord,
    Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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;
    int defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    (void)dummy;
    (void)state;

    /*
     * Get option values.
     */
    Tcl_GetIntFromObj(NULL, bd->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, bd->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, bd->reliefObj, &relief);
    Ttk_GetButtonDefaultStateFromObj(NULL, bd->defaultStateObj, &defaultState);

    if (defaultState == TTK_BUTTON_DEFAULT_ACTIVE) {
	GC gc = Tk_GCForColor(borderColor, d);
	XDrawRectangle(Tk_Display(tkwin), d, gc,
		b.x, b.y, b.width-1, b.height-1);
    }
    if (defaultState != TTK_BUTTON_DEFAULT_DISABLED) {
	/* Space for default ring: */
	b = Ttk_PadBox(b, Ttk_UniformPadding(1));
    }

    DrawBorder(tkwin, d, border, borderColor, b, borderWidth, relief);
}

static const Ttk_ElementSpec BorderElementSpec = {
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 */
    Tcl_Obj	*focusWidthObj;
    Tcl_Obj	*focusColorObj;
} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER, offsetof(FieldElement,borderObj),
static Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER, Tk_Offset(FieldElement,borderObj),
    	"white" },
    { "-bordercolor",TK_OPTION_COLOR, offsetof(FieldElement,borderColorObj),
    { "-bordercolor",TK_OPTION_COLOR, Tk_Offset(FieldElement,borderColorObj),
	"black" },
    { "-focuswidth", TK_OPTION_PIXELS, Tk_Offset(FieldElement,focusWidthObj),
	"2" },
    { "-focuscolor", TK_OPTION_COLOR, Tk_Offset(FieldElement,focusColorObj),
	"#4a6984" },
    { 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;

    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(2);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, field->borderColorObj);
    int focusWidth = 2;
    (void)dummy;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, field->focusWidthObj, &focusWidth);

    if (focusWidth > 0 && (state & TTK_STATE_FOCUS)) {
	Display *disp = Tk_Display(tkwin);
	XColor *focusColor = Tk_GetColorFromObj(tkwin, field->focusColorObj);
	GC focusGC = Tk_GCForColor(focusColor, d);

	if (focusWidth > 1) {
	    int x1 = b.x, x2 = b.x + b.width - 1;
	    int y1 = b.y, y2 = b.y + b.height - 1;
	    int w = WIN32_XDRAWLINE_HACK;
	    GC bgGC;

	    /*
	     * Draw the outer rounded rectangle
	     */
	    XDrawLine(disp, d, focusGC, x1+1, y1, x2-1+w, y1);	/* N */
	    XDrawLine(disp, d, focusGC, x1+1, y2, x2-1+w, y2);	/* S */
	    XDrawLine(disp, d, focusGC, x1, y1+1, x1, y2-1+w);	/* W */
	    XDrawLine(disp, d, focusGC, x2, y1+1, x2, y2-1+w);	/* E */

	    /*
	     * Draw the inner rectangle
	     */
	    b.x += 1; b.y += 1; b.width -= 2; b.height -= 2;
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);

	    /*
	     * Fill the inner rectangle
	     */
	    bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
	    XFillRectangle(disp, d, bgGC, b.x+1, b.y+1, b.width-2, b.height-2);
	} else {
	    /*
	     * Draw the field element as usual
	     */
    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_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
		0, TK_RELIEF_SUNKEN);
	    DrawFieldBorder(tkwin, d, border, borderColor, b);

	    /*
	     * Change the color of the border's outermost pixels
	     */
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);
	}
    } else {
	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
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472







-
+



















-
+







 * 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 */
    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[] = {
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
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502







-
+








static IndicatorSpec checkbutton_spec = {
    13, 13, 4,		/* width, height, nimages */
    checkbutton_pixels,
    checkbutton_states
};

static const Ttk_StateTable radiobutton_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
534
535
536

537
538
539
540
541
542
543
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







-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
-
+
+




-
+
+




-
-









-
-
+
+













+
+
+





-
+







    Tcl_Obj *colorObj;
    Tcl_Obj *lightColorObj;
    Tcl_Obj *shadeColorObj;
    Tcl_Obj *borderColorObj;
    Tcl_Obj *marginObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-background", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
	    Tk_Offset(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-foreground", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,foregroundObj), DEFAULT_FOREGROUND },
	    Tk_Offset(IndicatorElement,foregroundObj), DEFAULT_FOREGROUND },
    { "-indicatorcolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,colorObj), "#FFFFFF" },
	    Tk_Offset(IndicatorElement,colorObj), "#FFFFFF" },
    { "-lightcolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,lightColorObj), "#DDDDDD" },
	    Tk_Offset(IndicatorElement,lightColorObj), "#DDDDDD" },
    { "-shadecolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,shadeColorObj), "#888888" },
	    Tk_Offset(IndicatorElement,shadeColorObj), "#888888" },
    { "-bordercolor", TK_OPTION_COLOR,
	    offsetof(IndicatorElement,borderColorObj), "black" },
	    Tk_Offset(IndicatorElement,borderColorObj), "black" },
    { "-indicatormargin", TK_OPTION_STRING,
	    offsetof(IndicatorElement,marginObj), "0 2 4 2" },
	    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
	    Tk_Offset(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)
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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;
    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 = NULL;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);

    /*
     * Sanity check
     */
    if (   b.x < 0
	|| b.y < 0
	|| Tk_Width(tkwin) < b.x + spec->width
	|| Tk_Height(tkwin) < b.y + spec->height)
    {
	/* Oops!  not enough room to display the image.
	/* Oops!  Not enough room to display the image.
	 * Don't draw anything.
	 */
	return;
    }

    /*
     * Fill in imgColors palette:
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
646
647
648
649
650
651
652

653
654
655
656
657
658
659
660







-
+








    if (img == NULL) {
        return;
    }

#if defined(IGNORES_VISUAL)

    img->data = (char *)ckalloc(img->bytes_per_line * img->height);
    img->data = ckalloc(img->bytes_per_line * img->height);
    if (img->data == NULL) {
        XDestroyImage(img);
	return;
    }

#endif

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
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







-
+














+
+


+



-


-
+

-
+
+
+

-
+

-
+

-
+
-
-








-
+



-
+
+


-
-
+
+
-

-
-
-
+
+
+


+
+
+
+
+




-
+
+

-

+


+
+

-
+
-
-



-
-
-
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-


-
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



















-
+

-
+

-
-
-
+
+
+



-
+


+
-
-
+
+
+
+
+



-
-
-







+
-
-
+
+
+
+
+








-
-




















-
+







    ckfree(img->data);
    img->data = NULL;
#endif

    XDestroyImage(img);
}

static const Ttk_ElementSpec IndicatorElementSpec = {
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 *colorObj;		/* Arrow color */
    Tcl_Obj *borderObj;
    Tcl_Obj *borderColorObj;	/* Extra color for borders */
    Tcl_Obj *reliefObj;
    Tcl_Obj *colorObj;		/* Arrow color */
} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] = {
static Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) },
	Tk_Offset(ArrowElement,sizeObj), STRINGIFY(SCROLLBAR_WIDTH) },
    { "-arrowcolor", TK_OPTION_COLOR,
	Tk_Offset(ArrowElement,colorObj), "black"},
    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
	Tk_Offset(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR,
	offsetof(ArrowElement,borderColorObj), "black" },
	Tk_Offset(ArrowElement,borderColorObj), "black" },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj),"raised"},
	Tk_Offset(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 Ttk_Padding ArrowPadding = { 3,3,4,4 };

static void ArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    int width = SCROLLBAR_WIDTH;
    int direction = *(int *)clientData;
    int size = SCROLLBAR_WIDTH;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &width);
    width -= Ttk_PaddingWidth(ArrowPadding);
    TtkArrowSize(width/2, direction, widthPtr, heightPtr);
    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(ArrowPadding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(ArrowPadding);
    *heightPtr += Ttk_PaddingHeight(ArrowPadding);
    if (*widthPtr < *heightPtr) {
	*widthPtr = *heightPtr;
    } else {
	*heightPtr = *widthPtr;
    }
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
	ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int direction = *(int *)clientData;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, arrow->borderColorObj);
    int borderWidth = 2, relief = TK_RELIEF_RAISED;
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    int relief = TK_RELIEF_RAISED;
    GC gc = Tk_GCForColor(arrowColor, d);
    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);
    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);

    b = Ttk_PadBox(b, ArrowPadding);

    switch (direction) {
	case ARROW_UP:
	case ARROW_DOWN:
	    TtkArrowSize(b.width/2, direction, &cx, &cy);
	    if ((b.height - cy) % 2 == 1) {
		++cy;
	    }
	    break;
	case ARROW_LEFT:
	case ARROW_RIGHT:
	    TtkArrowSize(b.height/2, direction, &cx, &cy);
	    if ((b.width - cx) % 2 == 1) {
		++cx;
	    }
	    break;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);
	Ttk_PadBox(b, ArrowPadding), direction);
}

static const Ttk_ElementSpec ArrowElementSpec = {
static Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};

/*
 * Modified arrow element for comboboxes and spinboxes:
 * 	The width and height are different, and the left edge is drawn in the
 *	same color as the inner part of the right one.
 */

static void BoxArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int direction = *(int *)clientData;
    int size = SCROLLBAR_WIDTH;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(ArrowPadding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(ArrowPadding);
    *heightPtr += Ttk_PaddingHeight(ArrowPadding);
}

static void BoxArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int direction = *(int *)clientData;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    XColor *borderColor = Tk_GetColorFromObj(tkwin, arrow->borderColorObj);
    int borderWidth = 2, relief = TK_RELIEF_RAISED;
    Display *disp = Tk_Display(tkwin);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    int w = WIN32_XDRAWLINE_HACK;
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC arrowGC = Tk_GCForColor(arrowColor, d);

    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);

    XDrawLine(disp, d, darkGC, b.x, b.y+1, b.x, b.y+b.height-2+w);

    b = Ttk_PadBox(b, ArrowPadding);

    TtkArrowSize(b.width/2, direction, &cx, &cy);
    if ((b.height - cy) % 2 == 1) {
	++cy;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(disp, d, arrowGC, b, direction);
}

static Ttk_ElementSpec BoxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    BoxArrowElementSize,
    BoxArrowElementDraw
};

/*----------------------------------------------------------------------
 * +++ 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[] = {
static Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = {
    { "-direction", TK_OPTION_STRING,
	offsetof(MenubuttonArrowElement,directionObj), "below" },
	Tk_Offset(MenubuttonArrowElement,directionObj), "below" },
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(MenubuttonArrowElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(MenubuttonArrowElement,colorObj), "black"},
	Tk_Offset(MenubuttonArrowElement,sizeObj), STRINGIFY(MENUBUTTON_ARROW_SIZE)},
    { "-arrowcolor", TK_OPTION_COLOR,
	Tk_Offset(MenubuttonArrowElement,colorObj), "black"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const Ttk_Padding MenubuttonArrowPadding = { 3, 0, 3, 0 };
static Ttk_Padding MenubuttonArrowPadding = { 3, 0, 3, 0 };

static void MenubuttonArrowElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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
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







-
+

-
+

-
+

-
+

-
+

-
-
+
+



-
+


-
+

-
-
-










-
+


-
+

-
+
-
-
-


-
+


















-
+







    Tcl_Obj *colorObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *grooveWidthObj;
    Tcl_Obj *orientObj;
} TroughElement;

static const Ttk_ElementOptionSpec TroughElementOptions[] = {
static Ttk_ElementOptionSpec TroughElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(TroughElement, orientObj), "horizontal" },
	Tk_Offset(TroughElement, orientObj), "horizontal" },
    { "-troughborderwidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,borderWidthObj), "1" },
	Tk_Offset(TroughElement,borderWidthObj), "1" },
    { "-troughcolor", TK_OPTION_BORDER,
	offsetof(TroughElement,colorObj), DEFAULT_BACKGROUND },
	Tk_Offset(TroughElement,colorObj), DEFAULT_BACKGROUND },
    { "-troughrelief",TK_OPTION_RELIEF,
	offsetof(TroughElement,reliefObj), "sunken" },
	Tk_Offset(TroughElement,reliefObj), "sunken" },
    { "-groovewidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,grooveWidthObj), "-1" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
	Tk_Offset(TroughElement,grooveWidthObj), "-1" },
    { NULL, 0, 0, NULL }
};

static void TroughElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    TroughElement *troughPtr = 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,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    TroughElement *troughPtr = elementRecord;
    Tk_3DBorder border = NULL;
    int borderWidth = 2, relief = TK_RELIEF_SUNKEN, groove = -1;
    int borderWidth = 2, relief = TK_RELIEF_SUNKEN, groove = -1, orient;
    Ttk_Orient orient;
    (void)dummy;
    (void)state;

    border = Tk_Get3DBorderFromObj(tkwin, troughPtr->colorObj);
    TtkGetOrientFromObj(NULL, troughPtr->orientObj, &orient);
    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 const Ttk_ElementSpec TroughElementSpec = {
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
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
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







-
-
+
+

-
+

-
+

-
-
+
+




+
-
-
+
+
+
+
+


-
+

-
-


-
+











+
-
-
+
+
+
+
+






-
-















-
+



















-








-
+
-
-
-
+

-
+

-
-
-
+

-
+

+
+
-
+





+
-
-
+
+
+
+
+


-
-
+
+
-
-

-
+
-
-
-
+
+






-








+
-
-
+
+
+
+
+





-
-










-
+

















-
+


-
+

-
+

-
+

-
+




+
-
-
+
+
+
+
+


-
+

-
-

+
+

-
-
-
+
+



+
-
+








-






-
+















-
+











+
+
-
+










-
+

-
+










-
+
+
+

-
+
+
+
+
+

-
+

-
+

-
+


-
+







    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),
static Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-width", TK_OPTION_PIXELS, Tk_Offset(ThumbElement,sizeObj),
        STRINGIFY(SCROLLBAR_WIDTH) },
    { "-background", TK_OPTION_BORDER, offsetof(ThumbElement,borderObj),
    { "-background", TK_OPTION_BORDER, Tk_Offset(ThumbElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR, offsetof(ThumbElement,borderColorObj),
    { "-bordercolor", TK_OPTION_COLOR, Tk_Offset(ThumbElement,borderColorObj),
	"black" },
    { "-relief", TK_OPTION_RELIEF, offsetof(ThumbElement,reliefObj),"raised" },
    { "-orient", TK_OPTION_ANY, offsetof(ThumbElement,orientObj),"horizontal"},
    { "-relief", TK_OPTION_RELIEF, Tk_Offset(ThumbElement,reliefObj),"raised" },
    { "-orient", TK_OPTION_ANY, Tk_Offset(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int orient;
    int size;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, thumb->sizeObj, &size);
    TtkGetOrientFromObj(NULL, thumb->orientObj, &orient);
    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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
static Ttk_ElementSpec ThumbElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ThumbElement),
    ThumbElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};

/*
 *----------------------------------------------------------------------
 * +++ Slider element.
 *
 * This is the moving part of the scale widget.
 *
 * The slider element is the thumb in the scale widget. This is drawn
 * as an arrow-type element that can point up, down, left or right.
 *
 */

typedef struct {
    Tcl_Obj *lengthObj;		/* Long axis dimension */
    Tcl_Obj *thicknessObj;	/* Short axis dimension */
    Tcl_Obj *reliefObj;		/* Relief for this object */
    Tcl_Obj *borderObj;		/* Border / background color */
    Tcl_Obj *borderColorObj;	/* Additional border color */
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *orientObj;		/* Orientation of overall slider */
} SliderElement;

static const Ttk_ElementOptionSpec SliderElementOptions[] = {
static Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-sliderlength", TK_OPTION_PIXELS, offsetof(SliderElement,lengthObj),
	"15" },
    { "-sliderthickness",TK_OPTION_PIXELS, offsetof(SliderElement,thicknessObj),
    { "-sliderthickness", TK_OPTION_PIXELS, Tk_Offset(SliderElement,thicknessObj),
	"15" },
    { "-sliderrelief", TK_OPTION_RELIEF, offsetof(SliderElement,reliefObj),
    { "-sliderrelief", TK_OPTION_RELIEF, Tk_Offset(SliderElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SliderElement,borderWidthObj),
	STRINGIFY(BORDERWIDTH) },
    { "-background", TK_OPTION_BORDER, offsetof(SliderElement,borderObj),
    { "-background", TK_OPTION_BORDER, Tk_Offset(SliderElement,borderObj),
	DEFAULT_BACKGROUND },
    { "-bordercolor", TK_OPTION_COLOR, offsetof(ThumbElement,borderColorObj),
    { "-bordercolor", TK_OPTION_COLOR, Tk_Offset(SliderElement,borderColorObj),
	"black" },
    { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(SliderElement,borderWidthObj),
	STRINGIFY(BORDERWIDTH) },
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
    { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj),
	"horizontal" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int length, thickness, borderWidth;
    int orient;
    int thickness, borderWidth;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    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);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->thicknessObj, &thickness);
    Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth);

    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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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;
    Tcl_Obj *sizeObj;
} TreeitemIndicator;

static const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
	Tk_Offset(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
    { "-diameter", TK_OPTION_PIXELS,
	offsetof(TreeitemIndicator,diameterObj), "9" },
	Tk_Offset(TreeitemIndicator,sizeObj), "9" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginObj), "2 2 4 2" },
	Tk_Offset(TreeitemIndicator,marginObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    int diameter = 0;
    int size = 0;
    Ttk_Padding margins;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
    if (size % 2 == 0) --size;	/* An odd size is better for the indicator. */
    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->diameterObj, &diameter);
    *widthPtr = diameter + Ttk_PaddingWidth(margins);
    *heightPtr = diameter + Ttk_PaddingHeight(margins);
    *widthPtr = size + Ttk_PaddingWidth(margins);
    *heightPtr = size + Ttk_PaddingHeight(margins);
}

static void TreeitemIndicatorDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    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);
    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
    b = Ttk_PadBox(b, padding);

    XDrawRectangle(Tk_Display(tkwin), d, gc,
	    b.x, b.y, b.width - 1, b.height - 1);

    cx = b.x + (b.width - 1) / 2;
    cy = b.y + (b.height - 1) / 2;
    XDrawLine(Tk_Display(tkwin), d, gc, b.x+2, cy, b.x+b.width-3+w, cy);

    if (!(state & TTK_STATE_OPEN)) {
	/* turn '-' into a '+' */
	XDrawLine(Tk_Display(tkwin), d, gc, cx, b.y+2, cx, b.y+b.height-3+w);
    }
}

static const Ttk_ElementSpec TreeitemIndicatorElementSpec = {
static Ttk_ElementSpec TreeitemIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TreeitemIndicator),
    TreeitemIndicatorOptions,
    TreeitemIndicatorSize,
    TreeitemIndicatorDraw
};

/*------------------------------------------------------------------------
 * TtkAltTheme_Init --
 * 	Install alternate theme.
 */

MODULE_SCOPE int
MODULE_SCOPE int TtkAltTheme_Init(Tcl_Interp *interp)
TtkAltTheme_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_CreateTheme(interp, "alt", NULL);

    if (!theme) {
	return TCL_ERROR;
    }

    Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &IndicatorElementSpec, &checkbutton_spec);
	    &IndicatorElementSpec, (void *)&checkbutton_spec);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &IndicatorElementSpec, &radiobutton_spec);
	    &IndicatorElementSpec, (void *)&radiobutton_spec);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenubuttonArrowElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "trough", &TroughElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "slider", &SliderElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
	    &ArrowElementSpec, &ArrowElements[0]);
    Ttk_RegisterElement(interp, theme, "Spinbox.uparrow",
	    &BoxArrowElementSpec, &ArrowElements[0]);
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
	    &ArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "Spinbox.downarrow",
	    &BoxArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "Combobox.downarrow",
	    &BoxArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
	    &ArrowElementSpec, &ArrowElements[2]);
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
	    &ArrowElementSpec, &ArrowElements[3]);
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
	    &ArrowElementSpec, &ArrowElements[0]);

    Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
	    &TreeitemIndicatorElementSpec, 0);
	    &TreeitemIndicatorElementSpec, NULL);

    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
1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31









32
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) 2003, Joe English
 * Copyright (c) 2003 Joe English
 *
 * Default implementation for themed elements.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#if defined(_WIN32)
  #define WIN32_XDRAWLINE_HACK 1
#else
  #define WIN32_XDRAWLINE_HACK 0
#endif

#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 */ 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;
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    TCL_UNUSED(Ttk_Padding *))
{
}

/* public */ void
TtkNullElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(Drawable),
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_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,
64
65
66
67
68
69
70
71

72
73

74
75
76
77

78
79





80
81
82

83
84
85
86
87
88
89
90
91
92
93



94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130

131
132

133
134

135
136
137
138

139
140





141
142
143
144
145
146
147
148
149

150
151
152
153

154
155





156
157
158
159
160
161
162
163
164

165
166
167
168
169

170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187


188
189
190

191
192

193
194





195
196
197

198

199
200





201
202
203

204
205
206
207
208




209
210
211
212

213
214


215
216
217






































218
219
220
221
222
223
224
225
226
227




















228
229
230
231
232
233
234
66
67
68
69
70
71
72

73
74

75
76
77
78
79
80


81
82
83
84
85
86
87

88


89
90
91
92
93
94
95
96

97
98
99
100


101
102
103
104
105

106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133

134
135

136
137

138
139
140
141
142
143


144
145
146
147
148
149
150
151




152

153
154
155
156
157
158


159
160
161
162
163
164
165
166
167


168
169

170
171
172
173
174

175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199

200
201

202
203
204
205
206
207
208
209
210
211
212


213
214
215
216
217
218
219

220



221
222
223
224
225
226
227
228
229
230
231


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274










275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301







-
+

-
+




+
-
-
+
+
+
+
+


-
+
-
-








-
+
+
+

-
-





-
+







-
+

















-
+

-
+

-
+

-
+




+
-
-
+
+
+
+
+



-
-
-
-

-
+




+
-
-
+
+
+
+
+




-
-


-
+




-
+



-
+














+
+


-
+

-
+

-
+
+
+
+
+



+

+
-
-
+
+
+
+
+


-
+
-
-
-


+
+
+
+




+
-
-
+
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 * Ttk_GetLayout() automatically includes a background element.
 */

typedef struct {
    Tcl_Obj	*backgroundObj;
} BackgroundElement;

static const Ttk_ElementOptionSpec BackgroundElementOptions[] = {
static Ttk_ElementOptionSpec BackgroundElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	    offsetof(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND },
	    Tk_Offset(BackgroundElement,backgroundObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FillElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    BackgroundElement *bg = (BackgroundElement *)elementRecord;
    Tk_3DBorder backgroundPtr = Tk_Get3DBorderFromObj(tkwin,bg->backgroundObj);
    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)
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    Ttk_State state)
{
    (void)b;

    FillElementDraw(
	clientData, elementRecord, tkwin,
	d, Ttk_WinBox(tkwin), state);
}

static const Ttk_ElementSpec FillElementSpec = {
static Ttk_ElementSpec FillElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(BackgroundElement),
    BackgroundElementOptions,
    TtkNullElementSize,
    FillElementDraw
};

static const Ttk_ElementSpec BackgroundElementSpec = {
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 const Ttk_ElementOptionSpec BorderElementOptions[] = {
static Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(BorderElement,borderObj), DEFAULT_BACKGROUND },
	Tk_Offset(BorderElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
	Tk_Offset(BorderElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(BorderElement,reliefObj), "flat" },
	Tk_Offset(BorderElement,reliefObj), "flat" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void BorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(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);
    Tk_GetPixelsFromObj(NULL, tkwin, bd->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void BorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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_GetPixelsFromObj(NULL, tkwin, 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);
	    b.x, b.y, b.width, b.height, borderWidth, relief);
    }
}

static const Ttk_ElementSpec BorderElementSpec = {
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;
    Tcl_Obj	*focusWidthObj;
    Tcl_Obj	*focusColorObj;
} FieldElement;

static const Ttk_ElementOptionSpec FieldElementOptions[] = {
static Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
	offsetof(FieldElement,borderObj), "white" },
	Tk_Offset(FieldElement,borderObj), "white" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(FieldElement,borderWidthObj), "2" },
	Tk_Offset(FieldElement,borderWidthObj), "2" },
    { "-focuswidth", TK_OPTION_PIXELS,
	Tk_Offset(FieldElement,focusWidthObj), "2" },
    { "-focuscolor", TK_OPTION_COLOR,
	Tk_Offset(FieldElement,focusColorObj), "#4a6984" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};


static void FieldElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    FieldElement *field = (FieldElement *)elementRecord;
    int borderWidth = 2;
    int borderWidth = 2, focusWidth = 2;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, field->borderWidthObj, &borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, field->focusWidthObj, &focusWidth);
    if (focusWidth > 0 && borderWidth < 2) {
	borderWidth += (focusWidth - borderWidth);
    }
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    FieldElement *field = (FieldElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, field->borderObj);
    int focusWidth = 2;

    Tk_GetPixelsFromObj(NULL, tkwin, field->focusWidthObj, &focusWidth);

    if (focusWidth > 0 && (state & TTK_STATE_FOCUS)) {
	Display *disp = Tk_Display(tkwin);
	XColor *focusColor = Tk_GetColorFromObj(tkwin, field->focusColorObj);
	GC focusGC = Tk_GCForColor(focusColor, d);

	if (focusWidth > 1) {
	    int x1 = b.x, x2 = b.x + b.width - 1;
	    int y1 = b.y, y2 = b.y + b.height - 1;
	    int w = WIN32_XDRAWLINE_HACK;
	    GC bgGC;

	    /*
	     * Draw the outer rounded rectangle
	     */
	    XDrawLine(disp, d, focusGC, x1+1, y1, x2-1+w, y1);	/* N */
	    XDrawLine(disp, d, focusGC, x1+1, y2, x2-1+w, y2);	/* S */
	    XDrawLine(disp, d, focusGC, x1, y1+1, x1, y2-1+w);	/* W */
	    XDrawLine(disp, d, focusGC, x2, y1+1, x2, y2-1+w);	/* E */

	    /*
	     * Draw the inner rectangle
	     */
	    b.x += 1; b.y += 1; b.width -= 2; b.height -= 2;
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);

	    /*
	     * Fill the inner rectangle
	     */
	    bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
	    XFillRectangle(disp, d, bgGC, b.x+1, b.y+1, b.width-2, b.height-2);
	} else {
	    /*
	     * Draw the field element as usual
	     */
    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 = {
	    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);

	    /*
	     * Change the color of the border's outermost pixels
	     */
	    XDrawRectangle(disp, d, focusGC, b.x, b.y, b.width-1, b.height-1);
	}
    } else {
	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
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302


303
304
305
306

307

308




309
310
311
312
313














314
315
316



317
318
319
320
321
322
323
324
325







326
327
328
329

330
331





332
333
334
335
336
337
338
339
340

341
342
343
344

345
346





347
348
349
350

351
352
353
354




355
356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

379
380

381
382

383
384
385
386

387
388



389
390
391
392
393
394



395
396
397
398

399
400





401
402
403
404
405
406
407
408
409
410
411
412
413

414
415





416
417
418
419
420
421
422
423
424
425
426
427
428
429
430

431
432
433

434
435

436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
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
312
313
314
315
316
317
318

319
320

321
322



323
324
325
326
327
328
329
330


331
332
333
334
335
336
337
338
339
340



341
342


343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

371
372
373
374


375
376
377
378
379
380
381
382





383
384
385
386
387
388
389
390
391
392
393
394
395
396



397
398
399

400
401
402





403
404
405
406
407
408
409
410
411
412
413
414


415
416
417
418
419
420
421
422




423

424
425
426
427
428
429


430
431
432
433
434
435
436
437

438
439
440


441
442
443
444
445
446
447

448
449
450
451
452
453
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







-
+

-
+

-
-
-
+
+
+




+
-
-
+
+
+
+
+





-
-
-


-
-
+
+



-
+














+







-
+
+


-
-
+

+

+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-



-
-
-
-
-
+
+
+
+
+
+
+




+
-
-
+
+
+
+
+



-
-
-
-

-
+




+
-
-
+
+
+
+
+



-
+


-
-
+
+
+
+



-
+



















-
+

-
+

-
+




+
-
-
+
+
+
-
-
-
-
-
-
+
+
+




+
-
-
+
+
+
+
+





-
-






+
-
-
+
+
+
+
+





-
-







-
+


-
+

-
+












-
+







-
+







-
+















-
+

-
-
+
+



+
-
-
+
+
+
+
+


-
-
-
-
-




+
-
-
+
+
+
+
+







-
-



-
-
-
+
+
+



-
+








typedef struct {
    Tcl_Obj	*paddingObj;
    Tcl_Obj	*reliefObj;
    Tcl_Obj	*shiftreliefObj;
} PaddingElement;

static const Ttk_ElementOptionSpec PaddingElementOptions[] = {
static Ttk_ElementOptionSpec PaddingElementOptions[] = {
    { "-padding", TK_OPTION_STRING,
	offsetof(PaddingElement,paddingObj), "0" },
	Tk_Offset(PaddingElement,paddingObj), "0" },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(PaddingElement,reliefObj), "flat" },
    { "-shiftrelief", TK_OPTION_INT,
	offsetof(PaddingElement,shiftreliefObj), "0" },
	Tk_Offset(PaddingElement,reliefObj), "flat" },
    { "-shiftrelief", TK_OPTION_PIXELS,
	Tk_Offset(PaddingElement,shiftreliefObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PaddingElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(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);
    Tk_GetPixelsFromObj(NULL, tkwin, padding->shiftreliefObj, &shiftRelief);
    Ttk_GetPaddingFromObj(NULL, tkwin, padding->paddingObj, &pad);
    *paddingPtr = Ttk_RelievePadding(pad, relief, shiftRelief);
}

static const Ttk_ElementSpec PaddingElementSpec = {
static Ttk_ElementSpec PaddingElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(PaddingElement),
    PaddingElementOptions,
    PaddingElementSize,
    TtkNullElementDraw
};

/*----------------------------------------------------------------------
 * +++ Focus ring element.
 * 	Draws a dashed focus ring, if the widget has keyboard focus.
 */
typedef struct {
    Tcl_Obj	*focusColorObj;
    Tcl_Obj	*focusThicknessObj;
    Tcl_Obj	*focusSolidObj;
} FocusElement;

/*
 * DrawFocusRing --
 * 	Draw a dotted rectangle to indicate focus.
 */
static void DrawFocusRing(
    Tk_Window tkwin, Drawable d, Tcl_Obj *colorObj, Ttk_Box b)
    Tk_Window tkwin, Drawable d, Tcl_Obj *colorObj, int thickness, int solid,
    Ttk_Box b)
{
    XColor *color = Tk_GetColorFromObj(tkwin, colorObj);
    unsigned long mask = 0UL;
    XGCValues gcvalues;
    XGCValues gcValues;
    GC gc;
    Display *disp = Tk_Display(tkwin);

    if (thickness < 1 && solid) {
	thickness = 1;
    }

    gcvalues.foreground = color->pixel;
    gcvalues.line_style = LineOnOffDash;
    gcvalues.line_width = 1;
    gcvalues.dashes = 1;
    gcvalues.dash_offset = 1;
    gcValues.foreground = color->pixel;
    gc = Tk_GetGC(tkwin, GCForeground, &gcValues);

    if (solid) {
	XRectangle rects[4] = {
	    {b.x, b.y, b.width, thickness},				/* N */
	    {b.x, b.y + b.height - thickness, b.width, thickness},	/* S */
	    {b.x, b.y + thickness, thickness, b.height - 2*thickness},	/* W */
	    {b.x + b.width - thickness, b.y + thickness,		/* E */
	     thickness, b.height - 2*thickness}
	};

	XFillRectangles(disp, d, gc, rects, 4);
    } else {
    mask = GCForeground | GCLineStyle | GCDashList | GCDashOffset | GCLineWidth;

    gc = Tk_GetGC(tkwin, mask, &gcvalues);
	TkDrawDottedRect(disp, d, gc, b.x, b.y, b.width, b.height);
    }

    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" },
static Ttk_ElementOptionSpec FocusElementOptions[] = {
    { "-focuscolor", TK_OPTION_COLOR,
	Tk_Offset(FocusElement,focusColorObj), "black" },
    { "-focusthickness", TK_OPTION_PIXELS,
	Tk_Offset(FocusElement,focusThicknessObj), "1" },
    { "-focussolid", TK_OPTION_BOOLEAN,
	Tk_Offset(FocusElement,focusSolidObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void FocusElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(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);
    Tk_GetPixelsFromObj(NULL, tkwin, focus->focusThicknessObj, &focusThickness);
    *paddingPtr = Ttk_UniformPadding((short)focusThickness);
}

static void FocusElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    FocusElement *focus = (FocusElement *)elementRecord;
    int focusThickness = 0;
    (void)dummy;
    int focusSolid = 0;

    if (state & TTK_STATE_FOCUS) {
	Tcl_GetIntFromObj(NULL,focus->focusThicknessObj,&focusThickness);
	DrawFocusRing(tkwin, d, focus->focusColorObj, b);
	Tk_GetPixelsFromObj(NULL, tkwin, focus->focusThicknessObj, &focusThickness);
	Tcl_GetBooleanFromObj(NULL, focus->focusSolidObj, &focusSolid);
	DrawFocusRing(tkwin, d, focus->focusColorObj, focusThickness,
	    focusSolid, b);
    }
}

static const Ttk_ElementSpec FocusElementSpec = {
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 const Ttk_ElementOptionSpec SeparatorElementOptions[] = {
static Ttk_ElementOptionSpec SeparatorElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(SeparatorElement, orientObj), "horizontal" },
	Tk_Offset(SeparatorElement, orientObj), "horizontal" },
    { "-background", TK_OPTION_BORDER,
	offsetof(SeparatorElement,borderObj), DEFAULT_BACKGROUND },
	Tk_Offset(SeparatorElement,borderObj), DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SeparatorElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
{
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)paddingPtr;

    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    *widthPtr = *heightPtr = 2;
}

static void HorizontalSeparatorElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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)
    Drawable d, Ttk_Box b, Ttk_State state)
{
    SeparatorElement *separator = (SeparatorElement *)elementRecord;
    Ttk_Orient orient;
    int orient;

    TtkGetOrientFromObj(NULL, separator->orientObj, &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 const Ttk_ElementSpec HorizontalSeparatorElementSpec = {
static Ttk_ElementSpec HorizontalSeparatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SeparatorElement),
    SeparatorElementOptions,
    SeparatorElementSize,
    HorizontalSeparatorElementDraw
};

static const Ttk_ElementSpec VerticalSeparatorElementSpec = {
static Ttk_ElementSpec VerticalSeparatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SeparatorElement),
    SeparatorElementOptions,
    SeparatorElementSize,
    HorizontalSeparatorElementDraw
};

static const Ttk_ElementSpec SeparatorElementSpec = {
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 const Ttk_ElementOptionSpec SizegripOptions[] = {
static Ttk_ElementOptionSpec SizegripOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(SizegripElement,backgroundObj), DEFAULT_BACKGROUND },
    {0,TK_OPTION_BOOLEAN,0,0}
	Tk_Offset(SizegripElement,backgroundObj), DEFAULT_BACKGROUND },
    {0, TK_OPTION_BOOLEAN, 0, 0}
};

static void SizegripSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    int gripCount = 3, gripSpace = 2, gripThickness = 3;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)paddingPtr;

    *widthPtr = *heightPtr = gripCount * (gripSpace + gripThickness);
}

static void SizegripDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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;
	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 = {
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
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
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







-
+

-
+

-
+

-
+

-
+

-
+

-
+







-
+


-
+


-
-
-







-
+


-
+





-
-



-
-
-
+
+
+





-
+








-
+





-
-
-







-
-
+
+








-
-



-
-
-
+
+
+















-
-
+
+


-
+







-
+







    Tcl_Obj *reliefObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *diameterObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *borderWidthObj;
} IndicatorElement;

static const Ttk_ElementOptionSpec IndicatorElementOptions[] = {
static Ttk_ElementOptionSpec IndicatorElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
	Tk_Offset(IndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorcolor", TK_OPTION_BORDER,
	offsetof(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
	Tk_Offset(IndicatorElement,colorObj), DEFAULT_BACKGROUND },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(IndicatorElement,reliefObj), "raised" },
	Tk_Offset(IndicatorElement,reliefObj), "raised" },
    { "-indicatordiameter", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,diameterObj), "12" },
	Tk_Offset(IndicatorElement,diameterObj), "12" },
    { "-indicatormargin", TK_OPTION_STRING,
	offsetof(IndicatorElement,marginObj), "0 2 4 2" },
	Tk_Offset(IndicatorElement,marginObj), "0 2 4 2" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(IndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
	Tk_Offset(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,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    IndicatorElement *indicator = 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,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    IndicatorElement *indicator = (IndicatorElement *)elementRecord;
    IndicatorElement *indicator = 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);
    Tk_GetPixelsFromObj(NULL, tkwin, 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);
	    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,
    void *clientData, 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)
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State 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);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, indicator->reliefObj, &relief);
    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);

    b = Ttk_PadBox(b, padding);

    diameter = b.width < b.height ? b.width : b.height;
    radius = diameter / 2;

    points[0].x = b.x;
    points[0].y = b.y + radius;
    points[1].x = b.x + radius;
    points[1].y = b.y + 2*radius;
    points[2].x = b.x + 2*radius;
    points[2].y = b.y + radius;
    points[3].x = b.x + radius;
    points[3].y = b.y;

    Tk_Fill3DPolygon(tkwin,d,interior,points,4,borderWidth,TK_RELIEF_FLAT);
    Tk_Draw3DPolygon(tkwin,d,border,points,4,borderWidth,relief);
    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 = {
static Ttk_ElementSpec CheckbuttonIndicatorElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(IndicatorElement),
    IndicatorElementOptions,
    SquareIndicatorElementSize,
    SquareIndicatorElementDraw
};

static const Ttk_ElementSpec RadiobuttonIndicatorElementSpec = {
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
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







-
+

-
+

-
+

-
-
-
+
+
+

-
+

-
-
+
+



-
+


-
+

-
-
-


-
+





-
+


-
+



-
-

-
+






-
+














+
+

+
+



-
-


-
+
+
+
+
+

-
+
-
-

-
+
-
-
-
-
+
+



-
+



-
+
+


-
-
+
+
-

-
-
-
-
-
+
+
+
+
+
+
+
+
+
+




-
+
+

-

+

+
+

-
+
-
-

+


-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-


-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+











-
+

-
+

-
-
-
+
+
+




+
-
-
+
+
+
+
+

-
+

-
-
-






+
-
-
+
+
+




-
-









-
+







    Tcl_Obj *widthObj;
    Tcl_Obj *heightObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *marginObj;
} MenuIndicatorElement;

static const Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = {
    { "-background", TK_OPTION_BORDER,
	offsetof(MenuIndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
	Tk_Offset(MenuIndicatorElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-indicatorwidth", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,widthObj), "4.0m" },
	Tk_Offset(MenuIndicatorElement,widthObj), "4.0m" },
    { "-indicatorheight", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,heightObj), "1.7m" },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(MenuIndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
	Tk_Offset(MenuIndicatorElement,heightObj), "1.7m" },
    { "-indicatorborderwidth", TK_OPTION_PIXELS,
	Tk_Offset(MenuIndicatorElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-indicatorrelief", TK_OPTION_RELIEF,
	offsetof(MenuIndicatorElement,reliefObj),"raised" },
	Tk_Offset(MenuIndicatorElement,reliefObj), "raised" },
    { "-indicatormargin", TK_OPTION_STRING,
	    offsetof(MenuIndicatorElement,marginObj), "5 0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
	    Tk_Offset(MenuIndicatorElement,marginObj), "5 0" },
    { NULL, 0, 0, NULL }
};

static void MenuIndicatorElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    MenuIndicatorElement *mi = 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);
    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,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    MenuIndicatorElement *mi = (MenuIndicatorElement *)elementRecord;
    MenuIndicatorElement *mi = 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);
    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 = {
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 *sizeObj;
    Tcl_Obj *colorObj;
    Tcl_Obj *borderObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *colorObj;
} ArrowElement;

static const Ttk_ElementOptionSpec ArrowElementOptions[] = {
static Ttk_ElementOptionSpec ArrowElementOptions[] = {
    { "-arrowsize", TK_OPTION_PIXELS,
	Tk_Offset(ArrowElement,sizeObj), "14" },
    { "-arrowcolor", TK_OPTION_COLOR,
	Tk_Offset(ArrowElement,colorObj), "black"},
    { "-background", TK_OPTION_BORDER,
	offsetof(ArrowElement,borderObj), DEFAULT_BACKGROUND },
	Tk_Offset(ArrowElement,borderObj), DEFAULT_BACKGROUND },
    { "-relief",TK_OPTION_RELIEF,
	offsetof(ArrowElement,reliefObj),"raised"},
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ArrowElement,borderWidthObj), "1" },
	Tk_Offset(ArrowElement,borderWidthObj), "1" },
    { "-arrowcolor",TK_OPTION_COLOR,
	offsetof(ArrowElement,colorObj),"black"},
    { "-arrowsize", TK_OPTION_PIXELS,
	offsetof(ArrowElement,sizeObj), "14" },
    { "-relief", TK_OPTION_RELIEF,
	Tk_Offset(ArrowElement,reliefObj), "raised"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static const Ttk_Padding ArrowMargins = { 3,3,3,3 };
static Ttk_Padding ArrowPadding = { 3, 3, 3, 3 };

static void ArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    int width = 14;
    int direction = *(int *)clientData;
    int size = 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);
    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(ArrowPadding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(ArrowPadding);
    *heightPtr += Ttk_PaddingWidth(ArrowPadding);
    if (*widthPtr < *heightPtr) {
	*widthPtr = *heightPtr;
    } else {
	*heightPtr = *widthPtr;
    }
}

static void ArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ArrowDirection direction = (ArrowDirection)PTR2INT(clientData);
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int direction = *(int *)clientData;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    int borderWidth = 1, relief = TK_RELIEF_RAISED;
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    int relief = TK_RELIEF_RAISED;
    GC gc = Tk_GCForColor(arrowColor, d);
    int borderWidth = 1;
    (void)state;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->borderWidthObj, &borderWidth);
    Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);

    Tk_Fill3DRectangle( tkwin, d, border, b.x, b.y, b.width, b.height,
    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);

    b = Ttk_PadBox(b, ArrowPadding);

    switch (direction) {
	case ARROW_UP:
	case ARROW_DOWN:
	    TtkArrowSize(b.width/2, direction, &cx, &cy);
	    if ((b.height - cy) % 2 == 1) {
		++cy;
	    }
	    break;
	case ARROW_LEFT:
	case ARROW_RIGHT:
	    TtkArrowSize(b.height/2, direction, &cx, &cy);
	    if ((b.width - cx) % 2 == 1) {
		++cx;
	    }
	    break;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(Tk_Display(tkwin), d, Tk_GCForColor(arrowColor, d),
    TtkFillArrow(Tk_Display(tkwin), d, gc, b, direction);
	    Ttk_PadBox(b, ArrowMargins), direction);
}

static const Ttk_ElementSpec ArrowElementSpec = {
static Ttk_ElementSpec ArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    ArrowElementSize,
    ArrowElementDraw
};

/*
 * Modified arrow element for comboboxes and spinboxes:
 * 	The width and height are different, and the left edge is drawn in the
 *	same color as the right one.
 */

static void BoxArrowElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int direction = *(int *)clientData;
    int size = 14;

    Tk_GetPixelsFromObj(NULL, tkwin, arrow->sizeObj, &size);
    size -= Ttk_PaddingWidth(ArrowPadding);
    TtkArrowSize(size/2, direction, widthPtr, heightPtr);
    *widthPtr += Ttk_PaddingWidth(ArrowPadding);
    *heightPtr += Ttk_PaddingWidth(ArrowPadding);
}

static void BoxArrowElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ArrowElement *arrow = (ArrowElement *)elementRecord;
    int direction = *(int *)clientData;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, arrow->borderObj);
    int borderWidth = 1, relief = TK_RELIEF_RAISED;
    Display *disp = Tk_Display(tkwin);
    GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
    int w = WIN32_XDRAWLINE_HACK;
    int cx = 0, cy = 0;
    XColor *arrowColor = Tk_GetColorFromObj(tkwin, arrow->colorObj);
    GC arrowGC = Tk_GCForColor(arrowColor, d);

    Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
	    borderWidth, relief);

    XDrawLine(disp, d, darkGC, b.x, b.y+1, b.x, b.y+b.height-1+w);

    b = Ttk_PadBox(b, ArrowPadding);

    TtkArrowSize(b.width/2, direction, &cx, &cy);
    if ((b.height - cy) % 2 == 1) {
	++cy;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    TtkFillArrow(disp, d, arrowGC, b, direction);
}

static Ttk_ElementSpec BoxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ArrowElement),
    ArrowElementOptions,
    BoxArrowElementSize,
    BoxArrowElementDraw
};


/*
/*----------------------------------------------------------------------
 *----------------------------------------------------------------------
 * +++ 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[] = {
static Ttk_ElementOptionSpec TroughElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TroughElement,borderWidthObj), DEFAULT_BORDERWIDTH },
	Tk_Offset(TroughElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { "-troughcolor", TK_OPTION_BORDER,
	offsetof(TroughElement,colorObj), DEFAULT_BACKGROUND },
    { "-troughrelief",TK_OPTION_RELIEF,
	offsetof(TroughElement,reliefObj), "sunken" },
	Tk_Offset(TroughElement,colorObj), DEFAULT_BACKGROUND },
    { "-troughrelief", TK_OPTION_RELIEF,
	Tk_Offset(TroughElement,reliefObj), "sunken" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TroughElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    TroughElement *troughPtr = (TroughElement *)elementRecord;
    TroughElement *troughPtr = 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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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
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 *orientObj;
    Tcl_Obj *thicknessObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *borderObj;
    Tcl_Obj *borderWidthObj;
} ThumbElement;

static const Ttk_ElementOptionSpec ThumbElementOptions[] = {
static Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-orient", TK_OPTION_ANY,
	offsetof(ThumbElement, orientObj), "horizontal" },
	Tk_Offset(ThumbElement, orientObj), "horizontal" },
    { "-width", TK_OPTION_PIXELS,
	offsetof(ThumbElement,thicknessObj), DEFAULT_ARROW_SIZE },
	Tk_Offset(ThumbElement,thicknessObj), DEFAULT_ARROW_SIZE },
    { "-relief", TK_OPTION_RELIEF,
	offsetof(ThumbElement,reliefObj), "raised" },
	Tk_Offset(ThumbElement,reliefObj), "raised" },
    { "-background", TK_OPTION_BORDER,
	offsetof(ThumbElement,borderObj), DEFAULT_BACKGROUND },
	Tk_Offset(ThumbElement,borderObj), DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH },
	Tk_Offset(ThumbElement,borderWidthObj), DEFAULT_BORDERWIDTH },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ThumbElement *thumb = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int orient;
    int thickness;
    (void)dummy;
    (void)paddingPtr;

    Tk_GetPixelsFromObj(NULL, tkwin, thumb->thicknessObj, &thickness);
    TtkGetOrientFromObj(NULL, thumb->orientObj, &orient);
    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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+


-
+
-
-
+
-
-

-
+

















-
+


-
+

-
+
-
-
-


-
+







    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 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" },
    { "-sliderborderwidth", 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 *dummy, void *elementRecord, Tk_Window tkwin,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    SliderElement *slider = elementRecord;
    Ttk_Orient orient;
    int length, thickness;
    int orient, length, thickness;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    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 *dummy, void *elementRecord, Tk_Window tkwin,
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
{
    SliderElement *slider = (SliderElement *)elementRecord;
    SliderElement *slider = elementRecord;
    Tk_3DBorder border = NULL;
    int relief = TK_RELIEF_RAISED, borderWidth = 2;
    int relief = TK_RELIEF_RAISED, borderWidth = 2, orient;
    Ttk_Orient orient;
    (void)dummy;
    (void)state;

    border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj);
    TtkGetOrientFromObj(NULL, slider->orientObj, &orient);
    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
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
1254







-
+







		    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 = {
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
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
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







-
-
+
+

-
+

-
+

-
+

-
+

-
+





+
-
-
+
+
+


-
+

-
-

-
+

















+
-
-
+
+
+




-
-









-
+














+
+


-
+

-
+

-
-
+
+
+
+
+
+



+
-
-
+
+
+
+



-
-
+
+
-


+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+
-
-
+
+

+
+


-
-
+
+

-
-
-
+
+
+
+
+
+
+
-






+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+

-
-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+














-
-
-
+
+
+
+
+
+


-

-
-

-
-
+
+
-
-


-
-
-
+
+
+
+
+


+

-
-
-

-
-
+
+
+
+


-
+












-
-
+
+







-
+















-
+


-
+
+
+

-
+
+
+
+
+

-
+

-
+

-
+







    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),
static Ttk_ElementOptionSpec PbarElementOptions[] = {
    { "-orient", TK_OPTION_ANY, Tk_Offset(PbarElement,orientObj),
	"horizontal" },
    { "-thickness", TK_OPTION_PIXELS, offsetof(PbarElement,thicknessObj),
    { "-thickness", TK_OPTION_PIXELS, Tk_Offset(PbarElement,thicknessObj),
	DEFAULT_PBAR_THICKNESS },
    { "-barsize", TK_OPTION_PIXELS, offsetof(PbarElement,lengthObj),
    { "-barsize", TK_OPTION_PIXELS, Tk_Offset(PbarElement,lengthObj),
	DEFAULT_PBAR_LENGTH },
    { "-pbarrelief", TK_OPTION_RELIEF, offsetof(PbarElement,reliefObj),
    { "-pbarrelief", TK_OPTION_RELIEF, Tk_Offset(PbarElement,reliefObj),
	"raised" },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(PbarElement,borderWidthObj),
    { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(PbarElement,borderWidthObj),
	DEFAULT_BORDERWIDTH },
    { "-background", TK_OPTION_BORDER, offsetof(PbarElement,borderObj),
    { "-background", TK_OPTION_BORDER, Tk_Offset(PbarElement,borderObj),
	DEFAULT_BACKGROUND },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void PbarElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    PbarElement *pbar = (PbarElement *)elementRecord;
    Ttk_Orient orient;
    int orient;
    int thickness = 15, length = 30, borderWidth = 2;
    (void)dummy;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, pbar->orientObj, &orient);
    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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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;
    Tcl_Obj *highlightObj;
    Tcl_Obj *highlightColorObj;
} TabElement;

static const Ttk_ElementOptionSpec TabElementOptions[] = {
static Ttk_ElementOptionSpec TabElementOptions[] = {
    { "-borderwidth", TK_OPTION_PIXELS,
	offsetof(TabElement,borderWidthObj),"1" },
	Tk_Offset(TabElement,borderWidthObj), "1" },
    { "-background", TK_OPTION_BORDER,
	offsetof(TabElement,backgroundObj), DEFAULT_BACKGROUND },
    {0,TK_OPTION_BOOLEAN,0,0}
	Tk_Offset(TabElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-highlight", TK_OPTION_BOOLEAN,
	Tk_Offset(TabElement,highlightObj), "0" },
    { "-highlightcolor", TK_OPTION_COLOR,
	Tk_Offset(TabElement,highlightColorObj), "#4a6984" },
    {0, TK_OPTION_BOOLEAN, 0, 0}
};

static void TabElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord, Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    TabElement *tab = (TabElement *)elementRecord;
    int borderWidth = 1;
    (void)dummy;
    (void)widthPtr;
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
    paddingPtr->top = paddingPtr->left = paddingPtr->right = borderWidth;
    paddingPtr->bottom = 0;
}

	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    TabElement *tab = (TabElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    int borderWidth = 1;
    int cut = 2;
    int highlight = 0;
    XColor *hlColor = NULL;
    XPoint pts[6];
    int n = 0;
    (void)dummy;

    int cut = 2;
    Display *disp = Tk_Display(tkwin);
    int borderWidth = 1;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }
    Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth);

    if (state & TTK_STATE_SELECTED) {
	/*
	 * Draw slightly outside of the allocated parcel,
	 * to overwrite the client area border.
	 */
	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
	b.height += borderWidth;
    }
		b.height += 1;
		break;
	    case TTK_STICK_N:
		b.height += 1; b.y -= 1;
		break;
	    case TTK_STICK_E:
		b.width += 1;
		break;
	    case TTK_STICK_W:
		b.width += 1; b.x -= 1;
		break;
	}

	Tcl_GetBooleanFromObj(NULL, tab->highlightObj, &highlight);
	if (highlight) {
	    hlColor = Tk_GetColorFromObj(tkwin, tab->highlightColorObj);
	}
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
    pts[n].x = b.x; 			pts[n].y = b.y + b.height - 1; ++n;
    pts[n].x = b.x;			pts[n].y = b.y + cut; ++n;
    pts[n].x = b.x + cut;  		pts[n].y = b.y; ++n;
    pts[n].x = b.x + b.width-1-cut;	pts[n].y = b.y; ++n;
    pts[n].x = b.x + b.width-1; 	pts[n].y = b.y + cut; ++n;
    pts[n].x = b.x + b.width-1; 	pts[n].y = b.y + b.height; ++n;

    XFillPolygon(Tk_Display(tkwin), d,
	Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
	pts, 6, Convex, CoordModeOrigin);
	    pts[0].x = b.x;  pts[0].y = b.y + b.height-1;
	    pts[1].x = b.x;  pts[1].y = b.y + cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y + b.height;
	    break;
	case TTK_STICK_N:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x;  pts[1].y = b.y + b.height-1 - cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y + b.height-1;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y + b.height-1;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + b.height-1 - cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y-1;
	    break;
	case TTK_STICK_E:
	    pts[0].x = b.x + b.width-1;  pts[0].y = b.y;
	    pts[1].x = b.x + cut;  pts[1].y = b.y;
	    pts[2].x = b.x;  pts[2].y = b.y + cut;
	    pts[3].x = b.x;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x + b.width;  pts[5].y = b.y + b.height-1;
	    break;
	case TTK_STICK_W:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x + b.width-1 - cut;  pts[1].y = b.y;
	    pts[2].x = b.x + b.width-1;  pts[2].y = b.y + cut;
	    pts[3].x = b.x + b.width-1;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + b.width-1 - cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x-1;  pts[5].y = b.y + b.height-1;
	    break;
    }

    XFillPolygon(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
	    pts, 6, Convex, CoordModeOrigin);

    switch (nbTabsStickBit) {
#ifndef _WIN32
	default:
    /*
     * Account for whether XDrawLines draws endpoints by platform
     */
    --pts[5].y;
#endif

	case TTK_STICK_S:
	    pts[5].y -= 1 - WIN32_XDRAWLINE_HACK;
	    break;
	case TTK_STICK_N:
	    pts[5].y += 1 - WIN32_XDRAWLINE_HACK;
	    break;
	case TTK_STICK_E:
	    pts[5].x -= 1 - WIN32_XDRAWLINE_HACK;
	    break;
	case TTK_STICK_W:
	    pts[5].x += 1 - WIN32_XDRAWLINE_HACK;
	    break;
    }

    Tk_GetPixelsFromObj(NULL, tkwin, tab->borderWidthObj, &borderWidth);
    while (borderWidth--) {
	XDrawLines(Tk_Display(tkwin), d,
		Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
	XDrawLines(disp, 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),
	XDrawLines(disp, 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 = {

	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		++pts[0].x;  ++pts[1].x;  ++pts[2].y;
		++pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_N:
		++pts[0].x;  ++pts[1].x;  --pts[2].y;
		--pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_E:
		++pts[0].y;  ++pts[1].y;  ++pts[2].x;
		++pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	    case TTK_STICK_W:
		++pts[0].y;  ++pts[1].y;  --pts[2].x;
		--pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	}
    }

    if (highlight) {
	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x + cut, b.y, b.width - 2*cut, cut);
		break;
	    case TTK_STICK_N:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x + cut, b.y + b.height - cut, b.width - 2*cut, cut);
		break;
	    case TTK_STICK_E:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x, b.y + cut, cut, b.height - 2*cut);
		break;
	    case TTK_STICK_W:
		XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
			b.x + b.width - cut, b.y + cut, cut, b.height - 2*cut);
		break;
	}
    }
}

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 *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
static void ClientElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    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_GetPixelsFromObj(0, tkwin, ce->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)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)
static void ClientElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    ClientElement *ce = (ClientElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, ce->backgroundObj);
    int borderWidth = 1;
    (void)dummy;
    (void)widthPtr;
    (void)heightPtr;

    Tk_GetPixelsFromObj(0, tkwin, ce->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);
    Tk_GetPixelsFromObj(NULL, tkwin, ce->borderWidthObj, &borderWidth);

    Tk_Fill3DRectangle(tkwin, d, border,
	b.x, b.y, b.width, b.height, borderWidth, TK_RELIEF_RAISED);
}

static const Ttk_ElementSpec ClientElementSpec = {
static Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ClientElement),
    ClientElementOptions,
    ClientElementSize,
    ClientElementDraw
};

/*----------------------------------------------------------------------
 * TtkElements_Init --
 *	Register default element implementations.
 */

MODULE_SCOPE
void TtkElements_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkElements_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    /*
     * Elements:
     */
    Ttk_RegisterElement(interp, theme, "background",
	    &BackgroundElementSpec,NULL);
	    &BackgroundElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "fill", &FillElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "focus", &FocusElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "padding", &PaddingElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "Checkbutton.indicator",
	    &CheckbuttonIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Radiobutton.indicator",
	    &RadiobuttonIndicatorElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "Menubutton.indicator",
	    &MenuIndicatorElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec,NULL);
    Ttk_RegisterElement(interp, theme, "indicator", &ttkNullElementSpec, NULL);

    Ttk_RegisterElement(interp, theme, "uparrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
	    &ArrowElementSpec, &ArrowElements[0]);
    Ttk_RegisterElement(interp, theme, "Spinbox.uparrow",
	    &BoxArrowElementSpec, &ArrowElements[0]);
    Ttk_RegisterElement(interp, theme, "downarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_DOWN));
	    &ArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "Spinbox.downarrow",
	    &BoxArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "Combobox.downarrow",
	    &BoxArrowElementSpec, &ArrowElements[1]);
    Ttk_RegisterElement(interp, theme, "leftarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_LEFT));
	    &ArrowElementSpec, &ArrowElements[2]);
    Ttk_RegisterElement(interp, theme, "rightarrow",
	    &ArrowElementSpec, INT2PTR(ARROW_RIGHT));
	    &ArrowElementSpec, &ArrowElements[3]);
    Ttk_RegisterElement(interp, theme, "arrow",
	    &ArrowElementSpec, INT2PTR(ARROW_UP));
	    &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",
Changes to generic/ttk/ttkEntry.c.
8
9
10
11
12
13
14




15
16
17
18
19
20
21
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25







+
+
+
+







 * Copyright (c) 2004 Joe English
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Extra bits for core.flags:
 */
#define GOT_SELECTION		(WIDGET_USER_FLAG<<1)
#define SYNCING_VARIABLE	(WIDGET_USER_FLAG<<2)
#define VALIDATING		(WIDGET_USER_FLAG<<3)
#define VALIDATION_SET_VALUE	(WIDGET_USER_FLAG<<4)
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88


89
90
91
92



93
94
95
96
97
98
99
69
70
71
72
73
74
75

76
77
78
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 *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. */
    int numBytes;		/* Length of string in bytes. */
    int 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 */
    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
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 */

    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. */
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157

158
159

160
161
162

163
164
165

166
167
168

169
170
171
172
173
174

175
176
177

178
179
180

181
182
183
184


185
186

187
188
189

190
191
192

193
194
195
196
197
198
199
200
201

202
203

204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
144
145
146
147
148
149
150

151

152
153
154
155
156

157
158

159
160
161

162
163
164

165
166
167

168
169



170

171
172
173

174
175
176

177
178
179


180
181
182

183
184
185

186
187
188

189
190
191
192
193



194

195
196

197


198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
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 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_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[] = {
static Tk_OptionSpec EntryOptionSpecs[] = {
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
        "ExportSelection", "1", TCL_INDEX_NONE, offsetof(Entry, entry.exportSelection),
        "ExportSelection", "1", -1, Tk_Offset(Entry, entry.exportSelection),
	0,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, offsetof(Entry, entry.fontObj),TCL_INDEX_NONE,
	DEF_ENTRY_FONT, Tk_Offset(Entry, entry.fontObj),-1,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.invalidCmd),
	NULL, -1, Tk_Offset(Entry, entry.invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", TCL_INDEX_NONE, offsetof(Entry, entry.justify),
	"left", -1, Tk_Offset(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),
        NULL, -1, Tk_Offset(Entry, entry.showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Entry, entry.stateObj), TCL_INDEX_NONE,
	"normal", Tk_Offset(Entry, entry.stateObj), -1,
        0,0,STATE_CHANGED},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	NULL, offsetof(Entry, entry.textVariableObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(Entry, entry.textVariableObj), -1,
	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},
	"none", -1, Tk_Offset(Entry, entry.validate),
	TK_OPTION_ENUM_VAR, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.validateCmd),
	NULL, -1, Tk_Offset(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,
	DEF_ENTRY_WIDTH, Tk_Offset(Entry, entry.widthObj), -1,
	0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, entry.xscroll.scrollCmd),
	NULL, -1, Tk_Offset(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,
	NULL, Tk_Offset(Entry, entry.styleData.foregroundObj), -1,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
    {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
        "PlaceholderForeground", NULL,
        offsetof(Entry, entry.styleData.placeholderForegroundObj), TCL_INDEX_NONE,
	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(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);
}
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272







-










-







    /* 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);
}

/*------------------------------------------------------------------------
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

354
355

356
357
358

359
360
361
362

363
364

365
366
367
368
369


370
371
372
373
374
375
376
377



378
379
380
381
382
383
384
385
386
387
388

389
390
391
392

393
394
395
396
397
398
399
300
301
302
303
304
305
306


307


308
309
310
311
312








313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332

333
334
335

336
337
338
339

340
341

342
343
344
345


346
347
348



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369

370
371
372
373
374
375
376
377







-
-

-
-
+




-
-
-
-
-
-
-
-


















-
+

-
+


-
+



-
+

-
+



-
-
+
+

-
-
-




+
+
+










-
+



-
+








/* 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(
    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
static int
EntryFetchSelection(
    ClientData clientData, TkSizeT offset, char *buffer, TkSizeT maxBytes)
    void *clientData, int offset, char *buffer, int maxBytes)
{
    Entry *entryPtr = (Entry *)clientData;
    TkSizeT byteCount;
    int byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if (entryPtr->entry.selectFirst == TCL_INDEX_NONE || (!entryPtr->entry.exportSelection)
    if (entryPtr->entry.selectFirst < 0 || (!entryPtr->entry.exportSelection)
	    || Tcl_IsSafe(entryPtr->core.interp)) {
	return TCL_INDEX_NONE;
	return -1;
    }
    string = entryPtr->entry.displayString;

    selStart = Tcl_UtfAtIndex(string, entryPtr->entry.selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
    selStart = TkUtfAtIndex(string, entryPtr->entry.selectFirst);
    selEnd = TkUtfAtIndex(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;
    }
    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)
static void EntryLostSelection(void *clientData)
{
    Entry *entryPtr = (Entry *)clientData;
    entryPtr->core.flags &= ~GOT_SELECTION;
    entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    entryPtr->entry.selectFirst = entryPtr->entry.selectLast = -1;
    TtkRedisplayWidget(&entryPtr->core);
}

/* EntryOwnSelection --
 * 	Assert ownership of the PRIMARY selection,
 * 	if -exportselection set and selection is present and interp is unsafe.
 */
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+







 *	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 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;
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
443
444
445
446
447
448
449

450
451
452
453

454
455
456
457
458
459
460
461
462
463
464


465
466
467


468
469
470
471
472
473
474
475
476







-
+



-
+










-
-
+
+

-
-
+
+







		if (reason == VALIDATE_INSERT) {
		    number = 1;
		} else if (reason == VALIDATE_DELETE) {
		    number = 0;
		} else {
		    number = -1;
		}
		sprintf(numStorage, "%d", number);
		snprintf(numStorage, sizeof(numStorage), "%d", number);
		string = numStorage;
		break;
	    case 'i': /* index of insert/delete */
		sprintf(numStorage, "%d", (int)index);
		snprintf(numStorage, sizeof(numStorage), "%d", 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;
		    string = TkUtfAtIndex(newValue, index);
		    stringLength = TkUtfAtIndex(string, count) - string;
		} else if (reason == VALIDATE_DELETE) {
		    string = Tcl_UtfAtIndex(entryPtr->entry.string, index);
		    stringLength = Tcl_UtfAtIndex(string, count) - string;
		    string = TkUtfAtIndex(entryPtr->entry.string, index);
		    stringLength = TkUtfAtIndex(string, count) - string;
		} else {
		    string = "";
		    stringLength = 0;
		}
		break;
	    case 'v': /* type of validation currently set */
		string = validateStrings[entryPtr->entry.validate];
527
528
529
530
531
532
533
534
535


536
537
538
539
540
541
542
505
506
507
508
509
510
511


512
513
514
515
516
517
518
519
520







-
-
+
+







 */
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 */
    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, templ, newValue, index, count, reason, &script);
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
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







-
+








-
-
+
+







/* 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
 *	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 */
    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)
652
653
654
655
656
657
658
659




660
661
662
663
664
665
666
667
668
669
670
630
631
632
633
634
635
636

637
638
639
640
641
642
643

644
645
646
647
648
649
650







-
+
+
+
+



-







/* 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)
static int EntryRevalidate(
    TCL_UNUSED(Tcl_Interp *),
    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);
    }

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
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







-
-
+
+












-
+







    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;
    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);
    TkSizeT numChars = Tcl_NumUtfChars(value, numBytes);
    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)
831
832
833
834
835
836
837
838

839
840
841
842

843
844
845
846
847
848
849
811
812
813
814
815
816
817

818
819
820
821

822
823
824
825
826
827
828
829







-
+



-
+








/* 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 */
    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 byteIndex = TkUtfAtIndex(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) {
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
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







-
-
+
+






-
+


-
+


-
+



-
-
+
+








/* 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. */
    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 *newBytes;
    int code;

    if (index == TCL_INDEX_NONE) {
    if (index < 0) {
	index = 0;
    }
    if (count + index + 1 > entryPtr->entry.numChars + 1) {
    if (count + index > entryPtr->entry.numChars) {
	count = entryPtr->entry.numChars - index;
    }
    if (count + 1 <= 1) {
    if (count <= 0) {
	return TCL_OK;
    }

    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string+byteIndex, count) - (string+byteIndex);
    byteIndex = TkUtfAtIndex(string, index) - string;
    byteCount = TkUtfAtIndex(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(
921
922
923
924
925
926
927
928

929
930
931
932
933
934
935
901
902
903
904
905
906
907

908
909
910
911
912
913
914
915







-
+








/* EntryEventProc --
 *	Extra event handling for entry widgets:
 *	Triggers validation on FocusIn and FocusOut events.
 */
#define EntryEventMask (FocusChangeMask)
static void
EntryEventProc(ClientData clientData, XEvent *eventPtr)
EntryEventProc(void *clientData, XEvent *eventPtr)
{
    Entry *entryPtr = (Entry *)clientData;

    Tcl_Preserve(clientData);
    switch (eventPtr->type) {
	case DestroyNotify:
	    Tk_DeleteEventHandler(entryPtr->core.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
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







-
+
+
+


-



















-
-
+
+







}

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup.
 */

static void
EntryInitialize(Tcl_Interp *dummy, void *recordPtr)
EntryInitialize(
    TCL_UNUSED(Tcl_Interp *),
    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;
    entryPtr->entry.selectFirst 	= -1;
    entryPtr->entry.selectLast		= -1;
}

static void
EntryCleanup(void *recordPtr)
{
    Entry *entryPtr = (Entry *)recordPtr;

1025
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020







-
+







	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)
    if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst != -1)
	    && (!Tcl_IsSafe(entryPtr->core.interp))) {
	EntryOwnSelection(entryPtr);
    }

    /* Handle -state compatibility option:
     */
    if (mask & STATE_CHANGED) {
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
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







-
+
+
+
+



-

















-
+







    EntryUpdateTextLayout(entryPtr);
    return TCL_OK;
}

/* EntryPostConfigure --
 * 	Post-configuration hook for entry widgets.
 */
static int EntryPostConfigure(Tcl_Interp *dummy, void *recordPtr, int mask)
static int EntryPostConfigure(
    TCL_UNUSED(Tcl_Interp *),
    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)
EntryCharPosition(Entry *entryPtr, int index)
{
    int xPos;
    Tk_CharBbox(entryPtr->entry.textLayout, index, &xPos, NULL, NULL, NULL);
    return xPos + entryPtr->entry.layoutX;
}

/* EntryDoLayout --
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
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







-
+









-







-
-
+
+



-
-
-
+
+
+




-
+

-
+













-
+

-
+


+
+
+
+
+
+
-
+

-
-
+







/* 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,
    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;
    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
	&& entryPtr->entry.insertPos >= leftIndex
	&& entryPtr->entry.insertPos <= rightIndex
	;
    showSelection =
	   !(entryPtr->core.state & TTK_STATE_DISABLED)
	&& selFirst != TCL_INDEX_NONE
	&& selLast + 1 > leftIndex + 1
	&& selFirst + 1 <= rightIndex + 1;
	&& selFirst >= 0
	&& selLast > leftIndex
	&& selFirst <= rightIndex;

    /* Adjust selection range to keep in display bounds.
     */
    if (showSelection) {
	if (selFirst + 1 < leftIndex + 1)
	if (selFirst < leftIndex)
	    selFirst = leftIndex;
	if (selLast + 1 > rightIndex + 1)
	if (selLast > rightIndex)
	    selLast = rightIndex;
    }

    /* Draw widget background & border
     */
    Ttk_DrawLayout(entryPtr->core.layout, entryPtr->core.state, d);

    /* Draw selection background
     */
    if (showSelection && es.selBorderObj) {
	Tk_3DBorder selBorder = Tk_Get3DBorderFromObj(tkwin, es.selBorderObj);
	int selStartX = EntryCharPosition(entryPtr, selFirst);
	int selEndX = EntryCharPosition(entryPtr, selLast);
	int borderWidth = 1;
	int borderWidth = 0;

	Tcl_GetIntFromObj(NULL, es.selBorderWidthObj, &borderWidth);
	Tk_GetPixelsFromObj(NULL, tkwin, es.selBorderWidthObj, &borderWidth);

	if (selBorder) {
	    int selWidth;
	    int textareaEnd = textarea.x + textarea.width;
	    if (selEndX > textareaEnd)
		selEndX = textareaEnd;
	    selWidth = selEndX - selStartX + 2 * borderWidth;
	    if (selWidth > 0)
	    Tk_Fill3DRectangle(tkwin, d, selBorder,
		Tk_Fill3DRectangle(tkwin, d, selBorder,
		selStartX - borderWidth, entryPtr->entry.layoutY - borderWidth,
		selEndX - selStartX + 2*borderWidth,
		entryPtr->entry.layoutHeight + 2*borderWidth,
		selWidth, entryPtr->entry.layoutHeight + 2*borderWidth,
		borderWidth, TK_RELIEF_RAISED);
	}
    }

    /* Initialize the clip region. Note that Xft does _not_ derive its
     * clipping area from the GC, so we have to supply that by other means.
     */
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1262
1263
1264
1265
1266
1267
1268

1269
1270
1271
1272
1273
1274
1275
1276







-
+







    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);
	Tk_GetPixelsFromObj(NULL, tkwin, es.insertWidthObj, &cursorWidth);
	if (cursorWidth <= 0) {
	    cursorWidth = 1;
	}

	/* @@@ should: maybe: SetCaretPos even when blinked off */
	Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight);

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
1285
1286
1287
1288
1289
1290
1291















1292
1293
1294
1295
1296
1297
1298
1299







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







	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);
    gc = EntryGetGC(entryPtr, es.foregroundObj, clipRegion);
    if (showSelection) {

        /* Draw the selected and unselected portions separately.
	 */
	if (leftIndex < selFirst) {
	    Tk_DrawTextLayout(
		Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout,
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
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







-
+


-
-
-
+
+
-
-
-
-
-
+
+
+
-
-
-
-
-
-
+






-
+







 *	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 */
    int *indexPtr)		/* Return value */
{
#   define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */
    TkSizeT length, idx;
    const char *string;

    const char *string = Tcl_GetString(indexObj);
    size_t length = indexObj->length;
    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;

    if (strncmp(string, "end", length) == 0) {
	*indexPtr = entryPtr->entry.numChars;
    	return TCL_OK;
    }

    string = TkGetStringFromObj(indexObj, &length);

    if (strncmp(string, "insert", length) == 0) {
    } 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 == TCL_INDEX_NONE) {
	if (entryPtr->entry.selectFirst < 0) {
	    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) {
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
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







-
+










-
+



+
-
+
+
+
+
+
+
+



















-
+








-
+



















-
+














-
+







	    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) {
	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 && ((TkSizeT)*indexPtr + 1 < entryPtr->entry.numChars + 1 )) {
	if (roundUp && (*indexPtr < entryPtr->entry.numChars)) {
	    *indexPtr += 1;
	}
    } else {
	if (Tcl_GetIntFromObj(interp, indexObj, indexPtr) != TCL_OK) {
	goto badIndex;
	    goto badIndex;
	}
	if (*indexPtr < 0) {
	    *indexPtr = 0;
	} else if (*indexPtr > entryPtr->entry.numChars) {
	    *indexPtr = entryPtr->entry.numChars;
	}
    }
    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;
    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 + 1 > 1)) {
    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 = (Entry *)recordPtr;
    TkSizeT first, last;
    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 + 1 >= first + 1 && EntryEditable(entryPtr)) {
    if (last >= first && EntryEditable(entryPtr)) {
	return DeleteChars(entryPtr, first, last - first);
    }
    return TCL_OK;
}

/* $entry get --
 * 	Return the current value of the entry widget.
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
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







-
+








-
+












-
+







 * 	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;
    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, TkNewIndexObj(index));
    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 = (Entry *)recordPtr;
    TkSizeT index;
    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;
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
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







-
+
















-
+










-
+












-
-
+
+







{
    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;
    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 = (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));
	    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 = (Entry *)recordPtr;
    TkSizeT start, end;
    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 + 1 >= end + 1 ) {
	entryPtr->entry.selectFirst = entryPtr->entry.selectLast = TCL_INDEX_NONE;
    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;
1718
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1690
1691
1692
1693
1694
1695
1696

1697
1698
1699
1700
1701
1702
1703
1704







-
+







/* $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;
	int 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);
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
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







-
+













+
+
+
+
+
+
+
+
+
+









-
+








-
+

-
+


-
+


-
+












-
+







    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Entry widget definition.
 */

static const WidgetSpec EntryWidgetSpec = {
static WidgetSpec EntryWidgetSpec = {
    "TEntry",			/* className */
    sizeof(Entry), 		/* recordSize */
    EntryOptionSpecs, 		/* optionSpecs */
    EntryCommands,  		/* subcommands */
    EntryInitialize,     	/* initializeProc */
    EntryCleanup,		/* cleanupProc */
    EntryConfigure,		/* configureProc */
    EntryPostConfigure,  	/* postConfigureProc */
    TtkWidgetGetLayout, 	/* getLayoutProc */
    TtkWidgetSize, 		/* sizeProc */
    EntryDoLayout,		/* layoutProc */
    EntryDisplay		/* displayProc */
};

/*------------------------------------------------------------------------
 * Named indices for the combobox "current" command
 */
static const char *const comboboxCurrentIndexNames[] = {
    "end", NULL
};
enum comboboxCurrentIndices {
    INDEX_END
};

/*------------------------------------------------------------------------
 * +++ Combobox widget record.
 */

typedef struct {
    Tcl_Obj	*postCommandObj;
    Tcl_Obj	*valuesObj;
    Tcl_Obj	*heightObj;
    TkSizeT	currentIndex;
    int	currentIndex;
} ComboboxPart;

typedef struct {
    WidgetCore core;
    EntryPart entry;
    ComboboxPart combobox;
} Combobox;

static const Tk_OptionSpec ComboboxOptionSpecs[] = {
static Tk_OptionSpec ComboboxOptionSpecs[] = {
    {TK_OPTION_STRING, "-height", "height", "Height",
        DEF_LIST_HEIGHT, offsetof(Combobox, combobox.heightObj), TCL_INDEX_NONE,
        DEF_LIST_HEIGHT, Tk_Offset(Combobox, combobox.heightObj), -1,
	0,0,0 },
    {TK_OPTION_STRING, "-postcommand", "postCommand", "PostCommand",
        "", offsetof(Combobox, combobox.postCommandObj), TCL_INDEX_NONE,
        "", Tk_Offset(Combobox, combobox.postCommandObj), -1,
	0,0,0 },
    {TK_OPTION_STRING, "-values", "values", "Values",
        "", offsetof(Combobox, combobox.valuesObj), TCL_INDEX_NONE,
        "", 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 = (Combobox *)recordPtr;

    cb->combobox.currentIndex = TCL_INDEX_NONE;
    cb->combobox.currentIndex = -1;
    TtkTrackElementState(&cb->core);
    EntryInitialize(interp, recordPtr);
}

/* ComboboxConfigure --
 * 	Configuration hook for combobox widgets.
 */
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
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







-
+









-
-
+
+





-
+




-
+

-
+



-
+


+
-
+
+
+
+

+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
-
+



-
-
-
-
-
-







 * 	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;
    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 == TCL_INDEX_NONE
	     || currentIndex >= (TkSizeT)nValues
	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 < (TkSizeT)nValues; ++currentIndex) {
	    for (currentIndex = 0; currentIndex < nValues; ++currentIndex) {
		if (!strcmp(currentValue,Tcl_GetString(values[currentIndex]))) {
		    break;
		}
	    }
	    if (currentIndex >= (TkSizeT)nValues) {
	    if (currentIndex >= nValues) {
		/* Not found */
		currentIndex = TCL_INDEX_NONE;
		currentIndex = -1;
	    }
	}
	cbPtr->combobox.currentIndex = currentIndex;
	Tcl_SetObjResult(interp, TkNewIndexObj(currentIndex));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(currentIndex));
	return TCL_OK;
    } else if (objc == 3) {
        int result, index;
	TkSizeT idx;

        result = Tcl_GetIndexFromObj(NULL, objv[2], comboboxCurrentIndexNames,
                "", 0, &index);
        if (result == TCL_OK) {

            /*
             * The index is one of the named indices.
             */
	if (TCL_OK == TkGetIntForIndex(objv[2], nValues - 1, 0, &idx)) {
	    if (idx == TCL_INDEX_NONE || idx > (TkSizeT)nValues) {

	    switch (index) {
	    case INDEX_END:
	        /* "end" index */
		if (nValues <= 0) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "index \"end\" out of range"));
		    Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_RANGE", NULL);
		    return TCL_ERROR;
		}
                currentIndex = nValues - 1;
                break;
 	    default:
		Tcl_Panic("Unknown named index");
		return TCL_ERROR;
	    }
	} else {

            /*
             * The index should be just an integer.
             */

	    if (Tcl_GetIntFromObj(NULL, objv[2], &currentIndex) != TCL_OK) {
	        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		        "Incorrect index %s", Tcl_GetString(objv[2])));
	        Tcl_SetErrorCode(interp, "TTK", "COMBOBOX", "IDX_VALUE", NULL);
	        return TCL_ERROR;
	    }

	    if (currentIndex < 0 || currentIndex >= nValues) {
	        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		        "index \"%s\" out of range", Tcl_GetString(objv[2])));
		        "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?");
1916
1917
1918
1919
1920
1921
1922
1923

1924
1925
1926
1927
1928
1929
1930
1927
1928
1929
1930
1931
1932
1933

1934
1935
1936
1937
1938
1939
1940
1941







-
+







    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ComboboxWidgetSpec = {
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
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







-
+

-
+



-
+


-
+


-
+


-
+



-
+


-
+








typedef struct {
    WidgetCore core;
    EntryPart entry;
    SpinboxPart spinbox;
} Spinbox;

static const Tk_OptionSpec SpinboxOptionSpecs[] = {
static Tk_OptionSpec SpinboxOptionSpecs[] = {
    {TK_OPTION_STRING, "-values", "values", "Values",
        "", offsetof(Spinbox, spinbox.valuesObj), TCL_INDEX_NONE,
        "", Tk_Offset(Spinbox, spinbox.valuesObj), -1,
	0,0,0 },

    {TK_OPTION_DOUBLE, "-from", "from", "From",
	"0", offsetof(Spinbox,spinbox.fromObj), TCL_INDEX_NONE,
	"0", Tk_Offset(Spinbox,spinbox.fromObj), -1,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	"0", offsetof(Spinbox,spinbox.toObj), TCL_INDEX_NONE,
	"0", Tk_Offset(Spinbox,spinbox.toObj), -1,
	0,0,0 },
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	"1", offsetof(Spinbox,spinbox.incrementObj), TCL_INDEX_NONE,
	"1", Tk_Offset(Spinbox,spinbox.incrementObj), -1,
	0,0,0 },
    {TK_OPTION_STRING, "-format", "format", "Format",
	"", offsetof(Spinbox, spinbox.formatObj), TCL_INDEX_NONE,
	"", Tk_Offset(Spinbox, spinbox.formatObj), -1,
	0,0,0 },

    {TK_OPTION_STRING, "-command", "command", "Command",
	"", offsetof(Spinbox, spinbox.commandObj), TCL_INDEX_NONE,
	"", Tk_Offset(Spinbox, spinbox.commandObj), -1,
	0,0,0 },
    {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
	"0", offsetof(Spinbox,spinbox.wrapObj), TCL_INDEX_NONE,
	"0", Tk_Offset(Spinbox,spinbox.wrapObj), -1,
	0,0,0 },

    WIDGET_INHERIT_OPTIONS(EntryOptionSpecs)
};

/* SpinboxInitialize --
 * 	Initialization hook for spinbox widgets.
2028
2029
2030
2031
2032
2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2039
2040
2041
2042
2043
2044
2045

2046
2047
2048
2049
2050
2051
2052
2053







-
+







    { "state",  	TtkWidgetStateCommand,0 },
    { "set", 		EntrySetCommand,0 },
    { "validate",	EntryValidateCommand,0 },
    { "xview", 		EntryXViewCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec SpinboxWidgetSpec = {
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
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







-
+

-
+

-
+




+
-
-
+
+
+
+
+






-
-










-
+







 */

typedef struct {
    Tcl_Obj	*fontObj;
    Tcl_Obj	*widthObj;
} TextareaElement;

static const Ttk_ElementOptionSpec TextareaElementOptions[] = {
static Ttk_ElementOptionSpec TextareaElementOptions[] = {
    { "-font", TK_OPTION_FONT,
	offsetof(TextareaElement,fontObj), DEF_ENTRY_FONT },
	Tk_Offset(TextareaElement,fontObj), DEF_ENTRY_FONT },
    { "-width", TK_OPTION_INT,
	offsetof(TextareaElement,widthObj), "20" },
	Tk_Offset(TextareaElement,widthObj), "20" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TextareaElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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 = {
static Ttk_ElementSpec TextareaElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TextareaElement),
    TextareaElementOptions,
    TextareaElementSize,
    TtkNullElementDraw
};

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
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







-
-
-
-
-
-
+
+
+
+
+
+





+
-
-
+
+







    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)
	     TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM|TTK_STICK_E))
	 TTK_GROUP("Spinbox.padding", TTK_FILL_BOTH,
	     TTK_NODE("Spinbox.textarea", TTK_FILL_BOTH)))
    TTK_GROUP("Spinbox.field", TTK_PACK_TOP|TTK_FILL_X,
	TTK_GROUP("null", TTK_PACK_RIGHT,
	    TTK_NODE("Spinbox.uparrow", TTK_PACK_TOP|TTK_STICK_E)
	    TTK_NODE("Spinbox.downarrow", TTK_PACK_BOTTOM|TTK_STICK_E))
	TTK_GROUP("Spinbox.padding", TTK_FILL_BOTH,
	    TTK_NODE("Spinbox.textarea", TTK_FILL_BOTH)))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkEntry_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkEntry_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterElement(interp, themePtr, "textarea", &TextareaElementSpec, 0);

    Ttk_RegisterLayout(themePtr, "TEntry", EntryLayout);
    Ttk_RegisterLayout(themePtr, "TCombobox", ComboboxLayout);
Changes to generic/ttk/ttkFrame.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
22
23
24
25
26
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[] = {
static Tk_OptionSpec FrameOptionSpecs[] = {
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", NULL,
	offsetof(Frame,frame.borderWidthObj), TCL_INDEX_NONE,
	Tk_Offset(Frame,frame.borderWidthObj), -1,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
	offsetof(Frame,frame.paddingObj), TCL_INDEX_NONE,
	Tk_Offset(Frame,frame.paddingObj), -1,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL,
	offsetof(Frame,frame.reliefObj), TCL_INDEX_NONE,
	Tk_Offset(Frame,frame.reliefObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_PIXELS, "-width", "width", "Width", "0",
	offsetof(Frame,frame.widthObj), TCL_INDEX_NONE,
	Tk_Offset(Frame,frame.widthObj), -1,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_PIXELS, "-height", "height", "Height", "0",
	offsetof(Frame,frame.heightObj), TCL_INDEX_NONE,
	Tk_Offset(Frame,frame.heightObj), -1,
	0,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static const Ttk_Ensemble FrameCommands[] = {
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
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 = {
static WidgetSpec FrameWidgetSpec = {
    "TFrame",			/* className */
    sizeof(Frame),		/* recordSize */
    FrameOptionSpecs,		/* optionSpecs */
    FrameCommands,		/* subcommands */
    TtkNullInitialize,		/* initializeProc */
    TtkNullCleanup,		/* cleanupProc */
    FrameConfigure,		/* configureProc */
246
247
248
249
250
251
252
253

254
255

256
257
258

259
260
261

262
263
264

265
266
267
268
269
270
271
246
247
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[] = {
static Tk_OptionSpec LabelframeOptionSpecs[] = {
    {TK_OPTION_STRING, "-labelanchor", "labelAnchor", "LabelAnchor",
	"nw", offsetof(Labelframe, label.labelAnchorObj),TCL_INDEX_NONE,
	"nw", Tk_Offset(Labelframe, label.labelAnchorObj),-1,
        0,0,GEOMETRY_CHANGED},
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Labelframe,label.textObj), TCL_INDEX_NONE,
	Tk_Offset(Labelframe,label.textObj), -1,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	"-1", offsetof(Labelframe,label.underlineObj), TCL_INDEX_NONE,
	"-1", Tk_Offset(Labelframe,label.underlineObj), -1,
	0,0,0 },
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", NULL,
	TCL_INDEX_NONE, offsetof(Labelframe,label.labelWidget),
	-1, Tk_Offset(Labelframe,label.labelWidget),
	TK_OPTION_NULL_OK,0,LABELWIDGET_CHANGED|GEOMETRY_CHANGED },

    WIDGET_INHERIT_OPTIONS(FrameOptionSpecs)
};

/*
 * Labelframe style parameters:
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
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







-
+















-
+







	/* 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),
    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))
    TCL_UNUSED(int))
{
    Labelframe *lframe = (Labelframe *)managerData;

    lframe->label.labelWidget = 0;
}

static Ttk_ManagerSpec LabelframeManagerSpec = {
622
623
624
625
626
627
628
629

630
631
632
633
634
635
636
622
623
624
625
626
627
628

629
630
631
632
633
634
635
636







-
+







	Ttk_ManagerSizeChanged(lframePtr->label.mgr);
	Ttk_ManagerLayoutChanged(lframePtr->label.mgr);
    }

    return TCL_OK;
}

static const WidgetSpec LabelframeWidgetSpec = {
static WidgetSpec LabelframeWidgetSpec = {
    "TLabelframe",		/* className */
    sizeof(Labelframe),		/* recordSize */
    LabelframeOptionSpecs, 	/* optionSpecs */
    FrameCommands,		/* subcommands */
    LabelframeInitialize,	/* initializeProc */
    LabelframeCleanup,		/* cleanupProc */
    LabelframeConfigure,	/* configureProc */
650
651
652
653
654
655
656
657
658


659
660
661
662
663
664
665
666
667
668
669
650
651
652
653
654
655
656


657
658
659
660
661
662
663
664
665
666
667
668
669







-
-
+
+











	TTK_NODE("Label.text", TTK_FILL_BOTH))
TTK_END_LAYOUT

/* ======================================================================
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkFrame_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkFrame_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TFrame", FrameLayout);
    Ttk_RegisterLayout(theme, "TLabelframe", LabelframeLayout);
    Ttk_RegisterLayout(theme, "Label", LabelSublayout);

    RegisterWidget(interp, "ttk::frame", &FrameWidgetSpec);
    RegisterWidget(interp, "ttk::labelframe", &LabelframeWidgetSpec);
}

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
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# ttkGenStubs.tcl --
#
#	This script generates a set of stub files for a given
#	interface.
#
#
# Copyright (c) 1998-1999 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.
#
# SOURCE: tcl/tools/genStubs.tcl, revision 1.44
#
# CHANGES:
#	+ Second argument to "declare" is used as a status guard
#	  instead of a platform guard.
#	+ Allow trailing semicolon in function declarations
#

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 {}
    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.
#
# Results:
#	None.

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 "\[ \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]
    fconfigure $in -eofchar "\032 {}" -encoding utf-8
    set out [open ${file}.new w]
    fconfigure $out -translation lf -encoding utf-8

    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 iftxt {eltxt {}} {withCygwin 0}} {
    set text ""
    switch $plat {
	win {
	    append text "#if defined(_WIN32)"
	    if {$withCygwin} {
		append text " || defined(__CYGWIN__)"
	    }
	    append text " /* WIN */\n${iftxt}"
	    if {$eltxt ne ""} {
		append text "#else /* WIN */\n${eltxt}"
	    }
	    append text "#endif /* WIN */\n"
	}
	unix {
	    append text "#if !defined(_WIN32)"
	    if {$withCygwin} {
		append text " && !defined(__CYGWIN__)"
	    }
	    append text " && !defined(MAC_OSX_TCL)\
		    /* UNIX */\n${iftxt}"
	    if {$eltxt ne ""} {
		append text "#else /* UNIX */\n${eltxt}"
	    }
	    append text "#endif /* UNIX */\n"
	}
	macosx {
	    append text "#ifdef MAC_OSX_TCL /* MACOSX */\n${iftxt}"
	    if {$eltxt ne ""} {
		append text "#else /* MACOSX */\n${eltxt}"
	    }
	    append text "#endif /* MACOSX */\n"
	}
	aqua {
	    append text "#ifdef MAC_OSX_TK /* AQUA */\n${iftxt}"
	    if {$eltxt ne ""} {
		append text "#else /* AQUA */\n${eltxt}"
	    }
	    append text "#endif /* AQUA */\n"
	}
	x11 {
	    append text "#if !(defined(_WIN32)"
	    if {$withCygwin} {
		append text " || defined(__CYGWIN__)"
	    }
	    append text " || defined(MAC_OSX_TK))\
		    /* X11 */\n${iftxt}"
	    if {$eltxt ne ""} {
		append text "#else /* X11 */\n${eltxt}"
	    }
	    append text "#endif /* X11 */\n"
	}
	default {
	    append text "${iftxt}${eltxt}"
	}
    }
    return $text
}

# genStubs::emitSlots --
#
#	Generate the stub table slots for the given interface.  If there
#	are no generic slots, then one table is generated for each
#	platform, otherwise one table is generated for all platforms.
#
# 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 eq ""} {
	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 eq "void"} {
	    return $arg
	} else {
	    return
	}
    }
    set result [list [string trim $type] $name]
    if {$array ne ""} {
	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
    variable stubs
    variable libraryName
    lassign $decl rtype fname args

    append text "/* $index */\n"
    if {[info exists stubs($name,deprecated,$index)]} {
	append text "[string toupper $libraryName]_DEPRECATED(\"$stubs($name,deprecated,$index)\")\n"
	set line "$rtype"
    } elseif {[string range $rtype end-5 end] eq "MP_WUR"} {
	set line "$scspec [string trim [string range $rtype 0 end-6]]"
    } else {
	set line "$scspec $rtype"
    }
    set count [expr {2 - ([string length $line] / 8)}]
    if {$count >= 0} {
	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 eq ""} {
	append line $fname
	append text $line
	append text ";\n"
	return $text
    }
    append line $fname

    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 ", ...)"
	    if {[lindex $args end] eq "{const char *} format"} {
		append line " TCL_FORMAT_PRINTF(" [expr {[llength $args] - 1}] ", " [llength $args] ")"
	    }
	}
	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 ")"
	}
    }
    if {[string range $rtype end-5 end] eq "MP_WUR"} {
	append line " MP_WUR"
    }
    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 eq ""} {
	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
    variable stubs

    set lfname [string tolower [string index $fname 0]]
    append lfname [string range $fname 1 end]

    set text "    "
    if {[info exists stubs($name,deprecated,$index)]} {
	append text "TCL_DEPRECATED_API(\"$stubs($name,deprecated,$index)\") "
    } elseif {[info exists stubs($name,nostub,$index)]} {
	append text "TCL_DEPRECATED_API(\"$stubs($name,nostub,$index)\") "
    }
    if {$args eq ""} {
	append text $rtype " *" $lfname "; /* $index */\n"
	return $text
    }
    if {[string range $rtype end-8 end] eq "__stdcall"} {
	append text [string trim [string range $rtype 0 end-9]] " (__stdcall *" $lfname ") "
    } elseif {[string range $rtype 0 11] eq "TCL_NORETURN"} {
	append text "TCL_NORETURN1 " [string trim [string range $rtype 12 end]] " (*" $lfname ") "
    } elseif {[string range $rtype end-5 end] eq "MP_WUR"} {
	append text [string trim [string range $rtype 0 end-6]] " (*" $lfname ") "
    } else {
	append text $rtype " (*" $lfname ") "
    }
    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 ", ...)"
	    if {[lindex $args end] eq "{const char *} format"} {
		append text " TCL_FORMAT_PRINTF(" [expr {[llength $args] - 1}] ", " [llength $args] ")"
	    }
	}
	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 ")"
	}
    }

    if {[string range $rtype end-5 end] eq "MP_WUR"} {
	append text " MP_WUR"
    }
    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] eq ""} {
	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]

    if {$epoch ne ""} {
	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 {\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"
    if {$epoch ne ""} {
	append text "    int epoch;\n"
	append text "    int revision;\n"
    }
    if {[info exists hooks($name)]} {
	append text "    const ${capName}StubHooks *hooks;\n\n"
    } else {
	append text "    void *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
    upvar $textVar text
    set root 1

    set capName [string toupper [string index $name 0]]
    append capName [string range $name 1 end]

    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 {$name in $hooks($intf)} {
		set root 0
		break
	    }
	}
    }

    append text "\n"
    if {!$root} {
	append text "static "
    }
    append text "const ${capName}Stubs ${name}Stubs = \{\n    TCL_STUB_MAGIC,\n"
    if {$epoch ne ""} {
	set CAPName [string toupper $name]
	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 -encoding utf-8 $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.
27
28
29
30
31
32
33
34

35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
27
28
29
30
31
32
33

34
35

36








37
38
39
40
41
42
43







-
+

-
+
-
-
-
-
-
-
-
-







    Tk_ImageChangedProc *imageChanged;
    ClientData		imageChangedClientData;
};

/* NullImageChanged --
 * 	Do-nothing Tk_ImageChangedProc.
 */
static void NullImageChanged(ClientData dummy,
static void NullImageChanged(ClientData clientData,
    int x, int y, int width, int height, int imageWidth, int imageHeight)
{ /* No-op */
{ /* 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)
{
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84







-
+







TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr,
    Tk_ImageChangedProc *imageChangedProc, ClientData imageChangedClientData)
{
    Ttk_ImageSpec *imageSpec = 0;
    int i = 0, n = 0, objc;
    Tcl_Obj **objv;

    imageSpec = (Ttk_ImageSpec *)ckalloc(sizeof(*imageSpec));
    imageSpec = ckalloc(sizeof(*imageSpec));
    imageSpec->baseImage = 0;
    imageSpec->mapCount = 0;
    imageSpec->states = 0;
    imageSpec->images = 0;
    imageSpec->imageChanged = imageChangedProc;
    imageSpec->imageChangedClientData = imageChangedClientData;

101
102
103
104
105
106
107
108
109


110
111
112
113
114
115
116
93
94
95
96
97
98
99


100
101
102
103
104
105
106
107
108







-
-
+
+







		-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));
    imageSpec->states = ckalloc(n * sizeof(Ttk_StateSpec));
    imageSpec->images = 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;
160
161
162
163
164
165
166
167




168
169
170
171
172
173
174
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168
169







-
+
+
+
+








    ckfree(imageSpec);
}

/* TtkSelectImage --
 * 	Return a state-specific image from an ImageSpec
 */
Tk_Image TtkSelectImage(Ttk_ImageSpec *imageSpec, Ttk_State state)
Tk_Image TtkSelectImage(
    Ttk_ImageSpec *imageSpec,
    TCL_UNUSED(Tk_Window),
    Ttk_State state)
{
    int i;
    for (i = 0; i < imageSpec->mapCount; ++i) {
	if (Ttk_StateMatches(state, imageSpec->states+i)) {
	    return imageSpec->images[i];
	}
    }
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
204
205
206
207
208
209
210

211
212
213
214
215
216
217







-







 */
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) {
254
255
256
257
258
259
260
261

262
263
264
265
266

267
268
269
270
271
272
273
274

275
276

277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314

315
316
317
318
319
320
321
322

323
324
325

326
327
328
329
330
331
332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
248
249
250
251
252
253
254

255
256
257
258
259

260
261
262
263
264
265
266
267

268
269

270
271
272
273
274
275
276
277
278
279

280
281


282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

300
301
302
303

304

305
306
307
308
309
310
311
312

313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370

371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398







-
+




-
+







-
+

-
+









-
+

-
-


















-
+



-

-
+







-
+


-
+













-
+














-
+












-













-
+




-
+














-
+







/*------------------------------------------------------------------------
 * +++ Image element definition.
 */

typedef struct {		/* ClientData for image elements */
    Ttk_ImageSpec *imageSpec;	/* Image(s) to use */
    int minWidth;		/* Minimum width; overrides image width */
    int minHeight;		/* Minimum width; overrides image width */
    int minHeight;		/* Minimum height; overrides image height */
    Ttk_Sticky sticky;		/* -stickiness specification */
    Ttk_Padding border;		/* Fixed border region */
    Ttk_Padding padding;	/* Internal padding */

#ifdef TILE_07_COMPAT
#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 = (ImageData *)clientData;
    ImageData *imageData = clientData;
    if (imageData->imageSpec)	{ TtkFreeImageSpec(imageData->imageSpec); }
#ifdef TILE_07_COMPAT
#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 = (ImageData *)clientData;
    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;
    ImageData *imageData = clientData;
    Tk_Image image = 0;
    int imgWidth, imgHeight;
    Ttk_Box src, dst;
    (void)elementRecord;

#ifdef TILE_07_COMPAT
#if TILE_07_COMPAT
    if (imageData->imageMap) {
	Tcl_Obj *imageObj = Ttk_StateMapLookup(NULL,imageData->imageMap,state);
	if (imageObj) {
	    image = Ttk_UseImage(imageData->cache, tkwin, imageObj);
	}
    }
    if (!image) {
	image = TtkSelectImage(imageData->imageSpec, state);
	image = TtkSelectImage(imageData->imageSpec, tkwin, state);
    }
#else
    image = TtkSelectImage(imageData->imageSpec, state);
    image = TtkSelectImage(imageData->imageSpec, tkwin, state);
#endif

    if (!image) {
	return;
    }

    Tk_SizeOfImage(image, &imgWidth, &imgHeight);
    src = Ttk_MakeBox(0, 0, imgWidth, imgHeight);
    dst = Ttk_StickBox(b, imgWidth, imgHeight, imageData->sticky);

    Ttk_Tile(tkwin, d, image, src, dst, imageData->border);
}

static const Ttk_ElementSpec ImageElementSpec =
static Ttk_ElementSpec ImageElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ImageElementSize,
    ImageElementDraw
};

/*------------------------------------------------------------------------
 * +++ Image element factory.
 */
static int
Ttk_CreateImageElement(
    Tcl_Interp *interp,
    void *dummy,
    void *clientData,
    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 = 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
#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_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 TILE_07_COMPAT
	if (!strcmp("-map", Tcl_GetString(objv[i]))) {
	    imageData->imageMap = objv[i+1];
	    Tcl_IncrRefCount(imageData->imageMap);
	    continue;
	}
#endif

451
452
453
454
455
456
457
458
459


460
461
462
463
464
441
442
443
444
445
446
447


448
449
450
451
452
453
454







-
-
+
+





    return TCL_OK;

error:
    FreeImageData(imageData);
    return TCL_ERROR;
}

MODULE_SCOPE
void TtkImage_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkImage_Init(Tcl_Interp *interp)
{
    Ttk_RegisterElementFactory(interp, "image", Ttk_CreateImageElement, NULL);
}

/*EOF*/
Changes to generic/ttk/ttkInit.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
13
14
15
16
17
18
19

20
21



22
23
24



25
26
27
28
29
30
31
32
33
34
35
36

37
38



39
40
41



42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58












59
60
61
62
63
64
65







-
+

-
-
-
+
+
+
-
-
-












-
+

-
-
-
+
+
+
-
-
-










-







-
-
-
-
-
-
-
-
-
-
-
-







 * 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)
    Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr)
{
    int state = (int)TTK_BUTTON_DEFAULT_DISABLED;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkDefaultStrings,
	    sizeof(char *), "default state", 0, &state);
    *statePtr = TTK_BUTTON_DEFAULT_DISABLED;
    return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkDefaultStrings,
	    sizeof(char *), "default state", 0, statePtr);

    *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)
    Tcl_Interp *interp, Tcl_Obj *objPtr, int *statePtr)
{
    int compound = (int)TTK_COMPOUND_NONE;
    int result = Tcl_GetIndexFromObjStruct(interp, objPtr, ttkCompoundStrings,
	    sizeof(char *), "compound layout", 0, &compound);
    *statePtr = TTK_COMPOUND_NONE;
    return Tcl_GetIndexFromObjStruct(interp, objPtr, ttkCompoundStrings,
	    sizeof(char *), "compound layout", 0, statePtr);

    *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
119
120
121
122
123
124
125






















126
127
128
129
130
131
132
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    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>> -when tail"
 *
 * 	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 virt;} 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.virt.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
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 = (const Tk_OptionSpec *)specPtr->clientData;
	    specPtr = specPtr->clientData;
	}
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

int TtkGetOptionValue(
168
169
170
171
172
173
174
175

176
177
178

179
180

181
182

183
184
185
186
187
188
189
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 */
const Tk_OptionSpec ttkCoreOptionSpecs[] =
Tk_OptionSpec ttkCoreOptionSpecs[] =
{
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", NULL,
	offsetof(WidgetCore, cursorObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK,0,0 },
	Tk_Offset(WidgetCore, cursorObj), -1, TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_STRING, "-style", "style", "Style", "",
	offsetof(WidgetCore,styleObj), TCL_INDEX_NONE, 0,0,STYLE_CHANGED},
	Tk_Offset(WidgetCore,styleObj), -1, 0,0,STYLE_CHANGED},
    {TK_OPTION_STRING, "-class", "", "", NULL,
	offsetof(WidgetCore,classObj), TCL_INDEX_NONE, 0,0,READONLY_OPTION},
	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.
 */

Changes to generic/ttk/ttkLabel.c.
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51

52
53

54
55

56
57

58
59

60
61

62
63

64
65

66
67

68
69
70
71
72
73
74
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50

51
52

53
54

55
56

57
58

59
60

61
62

63
64

65
66

67
68
69
70
71
72
73
74







-
+















-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+







    Tcl_Obj	*fontObj;
    Tcl_Obj	*foregroundObj;
    Tcl_Obj	*underlineObj;
    Tcl_Obj	*widthObj;
    Tcl_Obj	*anchorObj;
    Tcl_Obj	*justifyObj;
    Tcl_Obj	*wrapLengthObj;
    Tcl_Obj     *embossedObj;
    Tcl_Obj	*embossedObj;

    /*
     * Computed resources:
     */
    Tk_Font		tkfont;
    Tk_TextLayout	textLayout;
    int 		width;
    int 		height;
    int			embossed;

} TextElement;

/* Text element options table.
 * NB: Keep in sync with label element option table.
 */
static const Ttk_ElementOptionSpec TextElementOptions[] = {
static Ttk_ElementOptionSpec TextElementOptions[] = {
    { "-text", TK_OPTION_STRING,
	offsetof(TextElement,textObj), "" },
	Tk_Offset(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(TextElement,fontObj), DEFAULT_FONT },
	Tk_Offset(TextElement,fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TextElement,foregroundObj), "black" },
	Tk_Offset(TextElement,foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	offsetof(TextElement,underlineObj), "-1"},
	Tk_Offset(TextElement,underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	offsetof(TextElement,widthObj), "-1"},
	Tk_Offset(TextElement,widthObj), "-1"},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(TextElement,anchorObj), "w"},
	Tk_Offset(TextElement,anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(TextElement,justifyObj), "left" },
	Tk_Offset(TextElement,justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,
	offsetof(TextElement,wrapLengthObj), "0" },
	Tk_Offset(TextElement,wrapLengthObj), "0" },
    { "-embossed", TK_OPTION_INT,
	offsetof(TextElement,embossedObj), "0"},
	Tk_Offset(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;
141
142
143
144
145
146
147
148

149
150

151
152
153
154
155
156
157
141
142
143
144
145
146
147

148
149

150
151
152
153
154
155
156
157







-
+

-
+







    /*
     * 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:
     * Clip text if it's too wide or too high:
     */
    if (b.width < text->width) {
    if (b.width < text->width || b.height < text->height) {
	XRectangle rect;

	clipRegion = TkCreateRegion();
	rect.x = b.x;
	rect.y = b.y;
	rect.width = b.width + (text->embossed ? 1 : 0);
	rect.height = b.height + (text->embossed ? 1 : 0);
189
190
191
192
193
194
195

196
197





198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216





217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
189
190
191
192
193
194
195
196


197
198
199
200
201
202
203


204
205
206
207
208
209
210
211
212
213
214
215
216
217


218
219
220
221
222
223
224


225
226
227
228
229
230
231

232
233
234
235
236
237
238
239







+
-
-
+
+
+
+
+


-
-













+
-
-
+
+
+
+
+


-
-







-
+







	TkDestroyRegion(clipRegion);
    }
    Tk_FreeGC(Tk_Display(tkwin), gc1);
    Tk_FreeGC(Tk_Display(tkwin), gc2);
}

static void TextElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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
251
252
253
254
255
256
257

258
259

260
261

262
263

264
265
266
267
268
269
270
271







-
+

-
+

-
+

-
+







    Tk_Image	tkimg;
    int 	width;
    int		height;
} ImageElement;

/* ===> NB: Keep in sync with label element option table.  <===
 */
static const Ttk_ElementOptionSpec ImageElementOptions[] = {
static Ttk_ElementOptionSpec ImageElementOptions[] = {
    { "-image", TK_OPTION_STRING,
	offsetof(ImageElement,imageObj), "" },
	Tk_Offset(ImageElement,imageObj), "" },
    { "-stipple", TK_OPTION_STRING, 	/* Really: TK_OPTION_BITMAP */
	offsetof(ImageElement,stippleObj), "gray50" },
	Tk_Offset(ImageElement,stippleObj), "gray50" },
    { "-background", TK_OPTION_COLOR,
	offsetof(ImageElement,backgroundObj), DEFAULT_BACKGROUND },
	Tk_Offset(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().
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296







-
+







    if (!image->imageObj) {
	return 0;
    }
    image->imageSpec = TtkGetImageSpec(NULL, tkwin, image->imageObj);
    if (!image->imageSpec) {
	return 0;
    }
    image->tkimg = TtkSelectImage(image->imageSpec, state);
    image->tkimg = TtkSelectImage(image->imageSpec, tkwin, state);
    if (!image->tkimg) {
	TtkFreeImageSpec(image->imageSpec);
	return 0;
    }
    Tk_SizeOfImage(image->tkimg, &image->width, &image->height);

    return 1;
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367

368
369





370
371
372
373
374
375
376
377
378
379
380
381
382

383
384





385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372


373
374
375
376
377
378
379


380
381
382
383
384
385
386
387
388
389


390
391
392
393
394
395
396

397
398
399
400
401
402
403

404
405
406
407
408
409
410
411







-
+








+
-
-
+
+
+
+
+


-
-









+
-
-
+
+
+
+
+


-







-
+







     * @@@ 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) {
	if (TtkSelectImage(image->imageSpec, tkwin, 0ul) == image->tkimg) {
#ifndef MAC_OSX_TK
	    StippleOver(image, tkwin, d, b.x,b.y);
#endif
	}
    }
}

static void ImageElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ImageElement *image = (ImageElement *)elementRecord;
    (void)dummy;
    (void)paddingPtr;

    if (ImageSetup(image, tkwin, 0)) {
	*widthPtr = image->width;
	*heightPtr = image->height;
	ImageCleanup(image);
    }
}

static void ImageElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
    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 = {
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
453
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







-
+

-
+

-
+





-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+





-
+

-
+

-
+











-
+






-
+







     * Computed values (see LabelSetup)
     */
    Ttk_Compound	compound;
    int  		space;
    int 		totalWidth, totalHeight;
} LabelElement;

static const Ttk_ElementOptionSpec LabelElementOptions[] = {
static Ttk_ElementOptionSpec LabelElementOptions[] = {
    { "-compound", TK_OPTION_ANY,
	offsetof(LabelElement,compoundObj), "none" },
	Tk_Offset(LabelElement,compoundObj), "none" },
    { "-space", TK_OPTION_PIXELS,
	offsetof(LabelElement,spaceObj), "4" },
	Tk_Offset(LabelElement,spaceObj), "4" },

    /* Text element part:
     * NB: Keep in sync with TextElementOptions.
     */
    { "-text", TK_OPTION_STRING,
	offsetof(LabelElement,text.textObj), "" },
	Tk_Offset(LabelElement,text.textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(LabelElement,text.fontObj), DEFAULT_FONT },
	Tk_Offset(LabelElement,text.fontObj), DEFAULT_FONT },
    { "-foreground", TK_OPTION_COLOR,
	offsetof(LabelElement,text.foregroundObj), "black" },
	Tk_Offset(LabelElement,text.foregroundObj), "black" },
    { "-underline", TK_OPTION_INT,
	offsetof(LabelElement,text.underlineObj), "-1"},
	Tk_Offset(LabelElement,text.underlineObj), "-1"},
    { "-width", TK_OPTION_INT,
	offsetof(LabelElement,text.widthObj), ""},
	Tk_Offset(LabelElement,text.widthObj), ""},
    { "-anchor", TK_OPTION_ANCHOR,
	offsetof(LabelElement,text.anchorObj), "w"},
	Tk_Offset(LabelElement,text.anchorObj), "w"},
    { "-justify", TK_OPTION_JUSTIFY,
	offsetof(LabelElement,text.justifyObj), "left" },
	Tk_Offset(LabelElement,text.justifyObj), "left" },
    { "-wraplength", TK_OPTION_PIXELS,
	offsetof(LabelElement,text.wrapLengthObj), "0" },
	Tk_Offset(LabelElement,text.wrapLengthObj), "0" },
    { "-embossed", TK_OPTION_INT,
	offsetof(LabelElement,text.embossedObj), "0"},
	Tk_Offset(LabelElement,text.embossedObj), "0"},

    /* Image element part:
     * NB: Keep in sync with ImageElementOptions.
     */
    { "-image", TK_OPTION_STRING,
	offsetof(LabelElement,image.imageObj), "" },
	Tk_Offset(LabelElement,image.imageObj), "" },
    { "-stipple", TK_OPTION_STRING, 	/* Really: TK_OPTION_BITMAP */
	offsetof(LabelElement,image.stippleObj), "gray50" },
	Tk_Offset(LabelElement,image.stippleObj), "gray50" },
    { "-background", TK_OPTION_COLOR,
	offsetof(LabelElement,image.backgroundObj), DEFAULT_BACKGROUND },
	Tk_Offset(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);
#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);
    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
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588







-
+







    if (c->compound != TTK_COMPOUND_TEXT)
	ImageCleanup(&c->image);
    if (c->compound != TTK_COMPOUND_IMAGE)
	TextCleanup(&c->text);
}

static void LabelElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    LabelElement *label = (LabelElement *)elementRecord;
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
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







-
+










-
+







/*
 * 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)
    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(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    LabelElement *l = (LabelElement *)elementRecord;
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
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







-
+











-
-
+
+








	    DrawCompound(l, b, tkwin, d, state, TTK_SIDE_RIGHT, TTK_SIDE_LEFT);
	    break;
    }

    LabelCleanup(l);
}

static const Ttk_ElementSpec LabelElementSpec = {
static Ttk_ElementSpec LabelElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(LabelElement),
    LabelElementOptions,
    LabelElementSize,
    LabelElementDraw
};

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkLabel_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkLabel_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme =  Ttk_GetDefaultTheme(interp);

    Ttk_RegisterElement(interp, theme, "text", &TextElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "image", &ImageElementSpec, NULL);
    Ttk_RegisterElement(interp, theme, "label", &LabelElementSpec, NULL);
}

Changes to generic/ttk/ttkLayout.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
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45




46
47
48
49
50
51
52
53
54
55
56











-
-
+
+



















+
+
+
+
+
+
+






-
-
-
-
+
+
+
+







/*
 * 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)
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))

/*------------------------------------------------------------------------
 * +++ Ttk_Box and Ttk_Padding utilities:
 */

Ttk_Box
Ttk_MakeBox(int x, int y, int width, int height)
{
    Ttk_Box b;
    b.x = x; b.y = y; b.width = width; b.height = height;
    return b;
}

int
Ttk_BoxContains(Ttk_Box box, int x, int y)
{
    return box.x <= x && x < box.x + box.width
	&& box.y <= y && y < box.y + box.height;
}

int
TtkBoxEqual(Ttk_Box box1, Ttk_Box box2)
{
    return box1.x == box2.x && box1.y == box2.y
	&& box1.width == box2.width && box1.height == box2.height;
}

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);
    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)
246
247
248
249
250
251
252

253
254
255
256
257
258
259
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267







+







	    Ttk_PackBox(cavity, width, height, side), width, height, sticky);
}

/*
 * Ttk_PositionBox --
 * 	Pack and stick a box according to PositionSpec flags.
 */

MODULE_SCOPE Ttk_Box
Ttk_PositionBox(Ttk_Box *cavity, int width, int height, Ttk_PositionSpec flags)
{
    Ttk_Box parcel;

	 if (flags & TTK_EXPAND)	parcel = *cavity;
    else if (flags & TTK_PACK_TOP)	parcel = packTop(cavity, height);
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542







-
+







    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));
    Ttk_LayoutNode *node = 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);

553
554
555
556
557
558
559
560
561


562
563
564
565
566
567
568
561
562
563
564
565
566
567


568
569
570
571
572
573
574
575
576







-
-
+
+







    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);
    Ttk_TemplateNode *op = 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)
{
839
840
841
842
843
844
845
846

847
848
849
850
851
852
853
847
848
849
850
851
852
853

854
855
856
857
858
859
860
861







-
+







};

static Ttk_Layout TTKNewLayout(
    Ttk_Style style,
    void *recordPtr,Tk_OptionTable optionTable, Tk_Window tkwin,
    Ttk_LayoutNode *root)
{
    Ttk_Layout layout = (Ttk_Layout)ckalloc(sizeof(*layout));
    Ttk_Layout layout = ckalloc(sizeof(*layout));
    layout->style = style;
    layout->recordPtr = recordPtr;
    layout->optionTable = optionTable;
    layout->tkwin = tkwin;
    layout->root = root;
    return layout;
}
Changes to generic/ttk/ttkManager.c.
30
31
32
33
34
35
36
37

38
39

40
41
42
43
44
45
46
30
31
32
33
34
35
36

37
38

39
40
41
42
43
44
45
46







-
+

-
+







 *
 * 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.
 * In case (1), Tk calls the manager's lostSlaveProc.
 * Case (2) is performed by calling Tk_ManageGeometry(window,NULL,0);
 * in this case Tk does _not_ call the lostContentProc (documented behavior).
 * 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 content window to track <Destroy> events.
 */

/* ++ Data structures.
 */
typedef struct
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71







-
+








struct TtkManager_
{
    Ttk_ManagerSpec	*managerSpec;
    void 		*managerData;
    Tk_Window   	window;
    unsigned		flags;
    TkSizeT 	 	nContent;
    int 	 	nContent;
    Ttk_Content 		**content;
};

/* manager->flags bits:
 */
#define MGR_UPDATE_PENDING	0x1
#define MGR_RESIZE_REQUIRED	0x2
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116







-
+







}

/* ++ RecomputeLayout --
 * 	Recompute geometry of all content windows.
 */
static void RecomputeLayout(Ttk_Manager *mgr)
{
    mgr->managerSpec->PlaceContent(mgr->managerData);
    mgr->managerSpec->PlaceSlaves(mgr->managerData);
    mgr->flags &= ~MGR_RELAYOUT_REQUIRED;
}

/* ++ ManagerIdleProc --
 * 	DoWhenIdle procedure for deferred updates.
 */
static void ManagerIdleProc(ClientData clientData)
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152







-
+







 * 	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;
    int i;

    switch (eventPtr->type)
    {
	case ConfigureNotify:
	    RecomputeLayout(mgr);
	    break;
	case MapNotify:
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184







-
+







 * 	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->managerSpec->tkGeomMgr.lostSlaveProc(
	    content->manager, content->window);
    }
}

/*------------------------------------------------------------------------
 * +++ Content initialization and cleanup.
 */
243
244
245
246
247
248
249
250

251
252

253
254
255
256
257
258
259
243
244
245
246
247
248
249

250
251

252
253
254
255
256
257
258
259







-
+

-
+







/*------------------------------------------------------------------------
 * +++ Content window management.
 */

/* ++ InsertContent --
 * 	Adds content to the list of managed windows.
 */
static void InsertContent(Ttk_Manager *mgr, Ttk_Content *content, TkSizeT index)
static void InsertContent(Ttk_Manager *mgr, Ttk_Content *content, int index)
{
    TkSizeT endIndex = mgr->nContent++;
    int 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;
    }

272
273
274
275
276
277
278
279

280
281
282

283
284
285
286

287
288
289
290
291
292
293
272
273
274
275
276
277
278

279
280
281

282
283
284
285

286
287
288
289
290
291
292
293







-
+


-
+



-
+







 * 	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)
static void RemoveContent(Ttk_Manager *mgr, int index)
{
    Ttk_Content *content = mgr->content[index];
    TkSizeT i;
    int i;

    /* Notify manager:
     */
    mgr->managerSpec->ContentRemoved(mgr->managerData, index);
    mgr->managerSpec->SlaveRemoved(mgr->managerData, index);

    /* Remove from array:
     */
    --mgr->nContent;
    for (i = index ; i < mgr->nContent; ++i) {
	mgr->content[i] = mgr->content[i+1];
    }
309
310
311
312
313
314
315
316
317
318





319
320
321


322
323


324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
309
310
311
312
313
314
315



316
317
318
319
320



321
322


323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389







-
-
-
+
+
+
+
+
-
-
-
+
+
-
-
+
+






-
+













-
+








-
+














-
+












-
+







/*------------------------------------------------------------------------
 * +++ 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);
    int index = Ttk_ContentIndex(mgr, window);

    if (index >= 0) {
	int reqWidth = Tk_ReqWidth(window);
	int reqHeight= Tk_ReqHeight(window);

    if (mgr->managerSpec->ContentRequest(
		mgr->managerData, index, reqWidth, reqHeight))
	if (mgr->managerSpec->SlaveRequest(
	    mgr->managerData, index, reqWidth, reqHeight)) {
    {
	ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
	    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);
    int 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_Manager *mgr, int 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)
void Ttk_ForgetContent(Ttk_Manager *mgr, int 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_Manager *mgr, int 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)
void Ttk_UnmapContent(Ttk_Manager *mgr, int 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:
     */
400
401
402
403
404
405
406
407

408
409
410
411

412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427

428
429

430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449

450
451
452
453
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
401
402
403
404
405
406
407

408
409
410
411

412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427

428
429

430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449

450
451
452
453
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







-
+



-
+



-
+











-
+

-
+



-
+












-
+


-
+




-
-
+
+

-
-
+
+











-
+



-
+







-
-
+
+






-
+







void Ttk_ManagerSizeChanged(Ttk_Manager *mgr)
{
    ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED);
}

/* +++ Accessors.
 */
TkSizeT Ttk_NumberContent(Ttk_Manager *mgr)
int Ttk_NumberContent(Ttk_Manager *mgr)
{
    return mgr->nContent;
}
void *Ttk_ContentData(Ttk_Manager *mgr, TkSizeT index)
void *Ttk_ContentData(Ttk_Manager *mgr, int index)
{
    return mgr->content[index]->data;
}
Tk_Window Ttk_ContentWindow(Ttk_Manager *mgr, TkSizeT index)
Tk_Window Ttk_ContentWindow(Ttk_Manager *mgr, int 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)
int Ttk_ContentIndex(Ttk_Manager *mgr, Tk_Window window)
{
    TkSizeT index;
    int index;
    for (index = 0; index < mgr->nContent; ++index)
	if (mgr->content[index]->window == window)
	    return index;
    return TCL_INDEX_NONE;
    return -1;
}

/* ++ 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)
    Tcl_Interp *interp, Ttk_Manager *mgr, Tcl_Obj *objPtr, int *indexPtr)
{
    const char *string = Tcl_GetString(objPtr);
    TkSizeT index = 0;
    int 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) {
    if (Tcl_GetIntFromObj(NULL, objPtr, &index) == TCL_OK) {
	if (index < 0 || index >= mgr->nContent) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"Managed window index %d out of bounds", (int)index));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "INDEX", NULL);
		"Slave index %d out of bounds", index));
	    Tcl_SetErrorCode(interp, "TTK", "SLAVE", "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) {
	if (index < 0) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s is not managed by %s", string,
		    Tk_PathName(mgr->window)));
	    Tcl_SetErrorCode(interp, "TTK", "MANAGED", "MANAGER", NULL);
	    Tcl_SetErrorCode(interp, "TTK", "SLAVE", "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);
	    "Invalid slave specification %s", string));
    Tcl_SetErrorCode(interp, "TTK", "SLAVE", "SPEC", NULL);
    return TCL_ERROR;
}

/* ++ Ttk_ReorderContent(mgr, fromIndex, toIndex) --
 * 	Change content window order.
 */
void Ttk_ReorderContent(Ttk_Manager *mgr, TkSizeT fromIndex, TkSizeT toIndex)
void Ttk_ReorderContent(Ttk_Manager *mgr, int fromIndex, int toIndex)
{
    Ttk_Content *moved = mgr->content[fromIndex];

    /* Shuffle down: */
    while (fromIndex > toIndex) {
	mgr->content[fromIndex] = mgr->content[fromIndex - 1];
	--fromIndex;
535
536
537
538
539
540
541
542

543
544
545
546
547
536
537
538
539
540
541
542

543
544
545
546
547
548







-
+





	}
	ancestor = Tk_Parent(ancestor);
    }

    return 1;

badWindow:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't add %s as content of %s",
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't add %s as slave of %s",
	    Tk_PathName(window), Tk_PathName(container)));
    Tcl_SetErrorCode(interp, "TTK", "GEOMETRY", "MAINTAINABLE", NULL);
    return 0;
}

Changes to generic/ttk/ttkManager.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
49
50
51
52

53
54

55
56
57


58
59
60


61
62
63

64
65

66
67
68
69


70
71
72
73
74
75
76
77
78
79
80



81
82

83
84

85
86
87
88
89


90
91
92
93


94
95
96
97


98
99
100
101
102
103
12
13
14
15
16
17
18

19
20
21

22
23
24
25

26
27
28
29
30
31
32



33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51

52
53

54
55


56
57
58


59
60
61
62

63
64

65
66
67


68
69
70
71
72
73
74
75
76
77



78
79
80
81

82
83

84
85
86
87


88
89
90
91


92
93
94
95


96
97
98
99
100
101
102
103







-
+


-
+



-
+






-
-
-
+
+
+





-
+










-
+

-
+

-
-
+
+

-
-
+
+


-
+

-
+


-
-
+
+








-
-
-
+
+
+

-
+

-
+



-
-
+
+


-
-
+
+


-
-
+
+






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
 * PlaceSlaves sets the position and size of all managed content windows
 * by calling Ttk_PlaceContent().
 *
 * ContentRemoved() is called immediately before a content window is removed.
 * SlaveRemoved() 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.
 * SlaveRequest() 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);
    void (*PlaceSlaves)(void *managerData);
    int  (*SlaveRequest)(void *managerData, int index, int w, int h);
    void (*SlaveRemoved)(void *managerData, int index);
} Ttk_ManagerSpec;

/*
 * Default implementations for Tk_GeomMgr hooks:
 */
#define Ttk_LostSlaveProc Ttk_LostContentProc
#define Ttk_LostContentProc Ttk_LostSlaveProc
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
#define Ttk_InsertContent  Ttk_InsertSlave
MODULE_SCOPE void Ttk_InsertContent(
    Ttk_Manager *, TkSizeT position, Tk_Window, void *clientData);
    Ttk_Manager *, int position, Tk_Window, void *data);

#define Ttk_ForgetSlave Ttk_ForgetContent
MODULE_SCOPE void Ttk_ForgetContent(Ttk_Manager *, TkSizeT index);
#define Ttk_ForgetContent Ttk_ForgetSlave
MODULE_SCOPE void Ttk_ForgetContent(Ttk_Manager *, int index);

#define Ttk_ReorderSlave Ttk_ReorderContent
MODULE_SCOPE void Ttk_ReorderContent(Ttk_Manager *, TkSizeT fromIndex, TkSizeT toIndex);
#define Ttk_ReorderContent Ttk_ReorderSlave
MODULE_SCOPE void Ttk_ReorderContent(Ttk_Manager *, int fromIndex, int toIndex);
    /* Rearrange content window positions */

#define Ttk_PlaceSlave Ttk_PlaceContent
#define Ttk_PlaceContent Ttk_PlaceSlave
MODULE_SCOPE void Ttk_PlaceContent(
    Ttk_Manager *, TkSizeT index, int x, int y, int width, int height);
    Ttk_Manager *, int 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);
#define Ttk_UnmapContent Ttk_UnmapSlave
MODULE_SCOPE void Ttk_UnmapContent(Ttk_Manager *, int 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_ContentIndex Ttk_SlaveIndex
MODULE_SCOPE int Ttk_ContentIndex(Ttk_Manager *, Tk_Window);
    /* Returns: index in content array of specified window, -1 if not found */

#define Ttk_GetSlaveIndexFromObj Ttk_GetContentIndexFromObj
#define Ttk_GetContentIndexFromObj Ttk_GetSlaveIndexFromObj
MODULE_SCOPE int Ttk_GetContentIndexFromObj(
    Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, TkSizeT *indexPtr);
    Tcl_Interp *, Ttk_Manager *, Tcl_Obj *, int *indexPtr);

/* Accessor functions:
 */
#define Ttk_NumberSlaves Ttk_NumberContent
MODULE_SCOPE TkSizeT Ttk_NumberContent(Ttk_Manager *);
#define Ttk_NumberContent Ttk_NumberSlaves
MODULE_SCOPE int Ttk_NumberContent(Ttk_Manager *);
    /* Returns: number of managed content windows */

#define Ttk_SlaveData Ttk_ContentData
MODULE_SCOPE void *Ttk_ContentData(Ttk_Manager *, TkSizeT index);
#define Ttk_ContentData Ttk_SlaveData
MODULE_SCOPE void *Ttk_ContentData(Ttk_Manager *, int index);
    /* Returns: client data associated with content window */

#define Ttk_SlaveWindow Ttk_ContentWindow
MODULE_SCOPE Tk_Window Ttk_ContentWindow(Ttk_Manager *, TkSizeT index);
#define Ttk_ContentWindow Ttk_SlaveWindow
MODULE_SCOPE Tk_Window Ttk_ContentWindow(Ttk_Manager *, int 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 */
Changes to generic/ttk/ttkNotebook.c.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * Copyright (c) 2004, Joe English
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkThemeInt.h"
#include "ttkWidget.h"
#include "ttkManager.h"

#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))

/*------------------------------------------------------------------------
51
52
53
54
55
56
57
58

59
60
61
62


63
64

65
66

67
68
69


70
71

72
73
74
75

76
77
78

79
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98


99
100
101

102
103
104
105
106
107
108
109
110

111
112
113


114
115
116


117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138


139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160







161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177

178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
51
52
53
54
55
56
57

58
59
60


61
62
63

64
65

66
67


68
69
70

71
72
73
74

75
76
77

78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96


97
98
99
100

101
102
103
104
105
106
107
108
109

110
111


112
113
114


115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185

186
187
188
189
190

191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212







-
+


-
-
+
+

-
+

-
+

-
-
+
+

-
+



-
+


-
+

-
+
















-
-
+
+


-
+








-
+

-
-
+
+

-
-
+
+


-
+


















-
+
+


+




















+
+
+
+
+
+
+











-
+




-
+




-
+













-
+







/* 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[] =
static Tk_OptionSpec TabOptionSpecs[] =
{
    {TK_OPTION_STRING_TABLE, "-state", "", "",
	"normal", TCL_INDEX_NONE, offsetof(Tab,state),
	0, (void *)TabStateStrings, 0 },
	"normal", -1, Tk_Offset(Tab,state),
	TK_OPTION_ENUM_VAR, TabStateStrings, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Tab,textObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
	Tk_Offset(Tab,textObj), -1, 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_Offset(Tab,imageObj), -1, 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 },
	NULL, Tk_Offset(Tab,compoundObj), -1,
	TK_OPTION_NULL_OK, ttkCompoundStrings, GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-underline", "underline", "Underline", "-1",
	offsetof(Tab,underlineObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
	Tk_Offset(Tab,underlineObj), -1, 0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0 }
};

static const Tk_OptionSpec PaneOptionSpecs[] =
static Tk_OptionSpec PaneOptionSpecs[] =
{
    {TK_OPTION_STRING, "-padding", "padding", "Padding", "0",
	offsetof(Tab,paddingObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
	Tk_Offset(Tab,paddingObj), -1, 0, 0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-sticky", "sticky", "Sticky", "nsew",
	offsetof(Tab,stickyObj), TCL_INDEX_NONE, 0, 0, GEOMETRY_CHANGED },
	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 */
    TkSizeT currentIndex;		/* index of currently selected tab */
    TkSizeT activeIndex;		/* index of currently active tab */
    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 windows */
    Ttk_Box clientArea;		/* Where to pack content widgets */
} NotebookPart;

typedef struct
{
    WidgetCore core;
    NotebookPart notebook;
} Notebook;

static const Tk_OptionSpec NotebookOptionSpecs[] =
static Tk_OptionSpec NotebookOptionSpecs[] =
{
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	offsetof(Notebook,notebook.widthObj),TCL_INDEX_NONE,
    {TK_OPTION_PIXELS, "-width", "width", "Width", "0",
	Tk_Offset(Notebook,notebook.widthObj),-1,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	offsetof(Notebook,notebook.heightObj),TCL_INDEX_NONE,
    {TK_OPTION_PIXELS, "-height", "height", "Height", "0",
	Tk_Offset(Notebook,notebook.heightObj),-1,
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_STRING, "-padding", "padding", "Padding", NULL,
	offsetof(Notebook,notebook.paddingObj),TCL_INDEX_NONE,
	Tk_Offset(Notebook,notebook.paddingObj),-1,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/* Notebook style options:
 */
typedef struct
{
    Ttk_PositionSpec	tabPosition;	/* Where to place tabs */
    Ttk_Padding 	tabMargins;	/* Margins around tab row */
    Ttk_PositionSpec 	tabPlacement;	/* How to pack tabs within tab row */
    Ttk_Orient		tabOrient;	/* ... */
    int 		minTabWidth;	/* Minimum tab width */
    Ttk_Padding 	padding;	/* External padding */
} NotebookStyle;

static void NotebookStyleOptions(Notebook *nb, NotebookStyle *nbstyle)
static void NotebookStyleOptions(
    Notebook *nb, NotebookStyle *nbstyle, Tk_Window tkwin)
{
    Tcl_Obj *objPtr;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;

    nbstyle->tabPosition = TTK_PACK_TOP | TTK_STICK_W;
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabposition", 0)) != 0) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPosition);
    }

    /* Guess default tabPlacement as function of tabPosition:
     */
    if (nbstyle->tabPosition & TTK_PACK_LEFT) {
	nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_E;
    } else if (nbstyle->tabPosition & TTK_PACK_RIGHT) {
	nbstyle->tabPlacement = TTK_PACK_TOP | TTK_STICK_W;
    } else if (nbstyle->tabPosition & TTK_PACK_BOTTOM) {
	nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_N;
    } else { /* Assume TTK_PACK_TOP */
	nbstyle->tabPlacement = TTK_PACK_LEFT | TTK_STICK_S;
    }
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabplacement", 0)) != 0) {
	TtkGetLabelAnchorFromObj(NULL, objPtr, &nbstyle->tabPlacement);
    }

    /* Save the stick bit for later.  One of the values
     * TTK_STICK_S, TTK_STICK_N, TTK_STICK_E, or TTK_STICK_W:
     */
    if (mainInfoPtr != NULL) {
	mainInfoPtr->ttkNbTabsStickBit = (nbstyle->tabPlacement & 0x0f);
    }

    /* Compute tabOrient as function of tabPlacement:
     */
    if (nbstyle->tabPlacement & (TTK_PACK_LEFT|TTK_PACK_RIGHT)) {
	nbstyle->tabOrient = TTK_ORIENT_HORIZONTAL;
    } else {
	nbstyle->tabOrient = TTK_ORIENT_VERTICAL;
    }

    nbstyle->tabMargins = Ttk_UniformPadding(0);
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-tabmargins", 0)) != 0) {
	Ttk_GetBorderFromObj(NULL, objPtr, &nbstyle->tabMargins);
	Ttk_GetPaddingFromObj(NULL, tkwin, objPtr, &nbstyle->tabMargins);
    }

    nbstyle->padding = Ttk_UniformPadding(0);
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-padding", 0)) != 0) {
	Ttk_GetPaddingFromObj(NULL,nb->core.tkwin,objPtr,&nbstyle->padding);
	Ttk_GetPaddingFromObj(NULL, tkwin, objPtr, &nbstyle->padding);
    }

    nbstyle->minTabWidth = DEFAULT_MIN_TAB_WIDTH;
    if ((objPtr = Ttk_QueryOption(nb->core.layout, "-mintabwidth", 0)) != 0) {
	Tcl_GetIntFromObj(NULL, objPtr, &nbstyle->minTabWidth);
	Tk_GetPixelsFromObj(NULL, tkwin, objPtr, &nbstyle->minTabWidth);
    }
}

/*------------------------------------------------------------------------
 * +++ Tab management.
 */

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) {
    if (Tk_InitOptions(interp, (char *)record, optionTable, window) != TCL_OK) {
	ckfree(record);
	return NULL;
    }

    return record;
}

213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236







-
+







    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,
    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
259
260
261
262
263
264
265

266
267

268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331







-
+

-
+








-
+






-
+














-
+



-
+




















-
+







}

/*
 * 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)
static int IdentifyTab(Notebook *nb, int x, int y)
{
    TkSizeT index;
    int 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;
    return -1;
}

/*
 * ActivateTab --
 * 	Set the active tab index, redisplay if necessary.
 */
static void ActivateTab(Notebook *nb, TkSizeT index)
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 visible tab, and USER2
 * 	is set for the rightmost visible tab.
 */
static Ttk_State TabState(Notebook *nb, TkSizeT index)
static Ttk_State TabState(Notebook *nb, int index)
{
    Ttk_State state = nb->core.state;
    Tab *itab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT i = 0;
    int 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) {
    for (i = Ttk_NumberContent(nb->notebook.mgr) - 1; i != -1; --i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER2;
	}
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370







-
+







 * 	(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;
    int 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);
381
382
383
384
385
386
387

388
389
390
391
392
393
394

395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415


416
417
418
419
420
421
422
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423


424
425
426
427
428
429
430
431
432







+






-
+

-
+

















-
-
+
+







 * Client area size determined by max size of content windows,
 * overridden by -width and/or -height if nonzero.
 */

static int NotebookSize(void *clientData, int *widthPtr, int *heightPtr)
{
    Notebook *nb = (Notebook *)clientData;
    Tk_Window nbwin = nb->core.tkwin;
    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;
    int i;

    NotebookStyleOptions(nb, &nbstyle);
    NotebookStyleOptions(nb, &nbstyle, nbwin);

    /* 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);
    Tk_GetPixelsFromObj(NULL, nb->core.tkwin, nb->notebook.widthObj, &reqWidth);
    Tk_GetPixelsFromObj(NULL, nb->core.tkwin, nb->notebook.heightObj, &reqHeight);
    if (reqWidth > 0)
	clientWidth = reqWidth;
    if (reqHeight > 0)
	clientHeight = reqHeight;

    /* Tab row:
     */
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
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







-
+










+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
















+

-
+







	Ttk_State tabState = TabState(nb, i);

	if (tab->state != TAB_STATE_HIDDEN) {
	    Ttk_Padding expand = Ttk_UniformPadding(0);
	    Tcl_Obj *expandObj = Ttk_QueryOption(tabLayout,"-expand",tabState);

	    if (expandObj) {
		Ttk_GetBorderFromObj(NULL, expandObj, &expand);
		Ttk_GetPaddingFromObj(NULL, nb->core.tkwin, expandObj, &expand);
	    }

	    tab->parcel =
		Ttk_ExpandBox(
		    Ttk_PositionBox(&tabrowBox,
			tab->width, tab->height, tabPlacement),
		    expand);
	}
    }
}

/*
 * 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, int 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);
}

/* NotebookDoLayout --
 *	Computes notebook layout and places tabs.
 *
 * Side effects:
 * 	Sets clientArea, used to place panes.
 */
static void NotebookDoLayout(void *recordPtr)
{
    Notebook *nb = (Notebook *)recordPtr;
    Tk_Window nbwin = nb->core.tkwin;
    Ttk_Box cavity = Ttk_WinBox(nbwin);
    int tabrowWidth = 0, tabrowHeight = 0;
    Ttk_Element clientNode = Ttk_FindElement(nb->core.layout, "client");
    Ttk_Box tabrowBox;
    NotebookStyle nbstyle;
    int currentIndex = nb->notebook.currentIndex;

    NotebookStyleOptions(nb, &nbstyle);
    NotebookStyleOptions(nb, &nbstyle, nbwin);

    /* Notebook internal padding:
     */
    cavity = Ttk_PadBox(cavity, nbstyle.padding);

    /* Layout for notebook background (base layout):
     */
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
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







+
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








-
-
+
+









-
+


-
+















-
+











-
+









-
-
+
+



-
+








-
+




















-
-
+
+

-
+



-
+











-
+








-
+









-
-
-
-
+
+
+
+









-
+







-
+







	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;

    if (!TtkBoxEqual(nb->notebook.clientArea, cavity)) {
    nb->notebook.clientArea = cavity;
}

	nb->notebook.clientArea = cavity;
	if (currentIndex >= 0) {
	    NotebookPlaceContent(nb, currentIndex);
	}
    }
/*
 * 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) {
    int currentIndex = nb->notebook.currentIndex;
    if (currentIndex >= 0) {
	NotebookDoLayout(nb);
	NotebookPlaceContent(nb, currentIndex);
    }
}

/*
 * SelectTab(nb, index) --
 * 	Change the currently-selected tab.
 */
static void SelectTab(Notebook *nb, TkSizeT index)
static void SelectTab(Notebook *nb, int index)
{
    Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, index);
    TkSizeT currentIndex = nb->notebook.currentIndex;
    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 != TCL_INDEX_NONE) {
    if (currentIndex >= 0) {
	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);
    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)
{
    TkSizeT nTabs = Ttk_NumberContent(nb->notebook.mgr);
    TkSizeT nextIndex;
    int nTabs = Ttk_NumberContent(nb->notebook.mgr);
    int nextIndex;

    /* Scan forward for following usable tab:
     */
    for (nextIndex = index + 1; nextIndex + 1 < nTabs + 1; ++nextIndex) {
    for (nextIndex = index + 1; nextIndex < nTabs; ++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) {
    for (nextIndex = index - 1; nextIndex >= 0; --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);
    int currentIndex = nb->notebook.currentIndex;
    int nextIndex = NextTab(nb, currentIndex);

    if (currentIndex != TCL_INDEX_NONE) {
    if (currentIndex >= 0) {
	Ttk_UnmapContent(nb->notebook.mgr, currentIndex);
    }
    if (currentIndex != nextIndex) {
	Tk_SendVirtualEvent(nb->core.tkwin, "NotebookTabChanged", NULL);
	TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged");
    }

    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)
static void TabRemoved(void *managerData, int 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) {
    if (index < nb->notebook.currentIndex) {
	--nb->notebook.currentIndex;
    }

    DestroyTab(nb, tab);

    TtkRedisplayWidget(&nb->core);
}

static int TabRequest(
    TCL_UNUSED(void *),
    TCL_UNUSED(TkSizeT),
    TCL_UNUSED(int),
    TCL_UNUSED(int))
    TCL_UNUSED(void *), /* managerData */
    TCL_UNUSED(int), /* index */
    TCL_UNUSED(int), /* width */
    TCL_UNUSED(int)) /* height */
{
    return 1;
}

/* AddTab --
 * 	Add new tab at specified index.
 */
static int AddTab(
    Tcl_Interp *interp, Notebook *nb,
    TkSizeT destIndex, Tk_Window window,
    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_ContentIndex(nb->notebook.mgr, window) != TCL_INDEX_NONE) {
    if (Ttk_ContentIndex(nb->notebook.mgr, window) >= 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s already added",
	    Tk_PathName(window)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "PRESENT", NULL);
	return TCL_ERROR;
    }
#endif

754
755
756
757
758
759
760
761

762
763

764
765
766
767
768
769
770
770
771
772
773
774
775
776

777
778

779
780
781
782
783
784
785
786







-
+

-
+







	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) {
    if (nb->notebook.currentIndex < 0) {
	SelectTab(nb, destIndex);
    } else if (nb->notebook.currentIndex + 1 >= destIndex + 1) {
    } else if (nb->notebook.currentIndex >= destIndex) {
	++nb->notebook.currentIndex;
    }

    return TCL_OK;
}

static Ttk_ManagerSpec NotebookManagerSpec = {
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798

799
800
801
802
803
804
805
799
800
801
802
803
804
805

806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821







-
+







-
+







 * 	Tracks the active tab.
 */
static const int NotebookEventMask
    = StructureNotifyMask
    | PointerMotionMask
    | LeaveWindowMask
    ;
static void NotebookEventHandler(ClientData clientData, XEvent *eventPtr)
static void NotebookEventHandler(void *clientData, XEvent *eventPtr)
{
    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);
	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
835
836
837
838
839
840
841

842
843
844
845
846

847
848
849
850
851
852
853
854







-
+




-
+







 *
 *	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)
    Tcl_Interp *interp, Notebook *nb, Tcl_Obj *objPtr, int *index_rtn)
{
    const char *string = Tcl_GetString(objPtr);
    int x, y;

    *index_rtn = TCL_INDEX_NONE;
    *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;
    }
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
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







-
-
-
-
-
-












-
+


-
-
-
-
-
-
+
-
-
+







    /* ... 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)
    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 + 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) {
    if (status == TCL_OK && *index_rtn < 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "tab '%s' not found", Tcl_GetString(objPtr)));
	Tcl_SetErrorCode(interp, "TTK", "NOTEBOOK", "TAB", NULL);
	status = TCL_ERROR;
    }
    return status;
}
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
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







-
-
-
+
+
+


-
+



+
+
-
+















-
+






-
-












-
+






-
+


-
+

-
+















-
+







/* $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;
    int current = nb->notebook.currentIndex;
    int nContent = Ttk_NumberContent(nb->notebook.mgr);
    int srcIndex, destIndex;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?");
	return TCL_ERROR;
    }

    if (!strcmp(Tcl_GetString(objv[2]), "end")) {
	destIndex = Ttk_NumberContent(nb->notebook.mgr);
    if (TCL_OK != Ttk_GetContentIndexFromObj(
    } else 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 */
	if (srcIndex < 0) {	/* 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) {
    if (destIndex >= nContent) {
	destIndex  = nContent - 1;
    }
    Ttk_ReorderContent(nb->notebook.mgr, srcIndex, destIndex);

    /* Adjust internal indexes:
     */
    nb->notebook.activeIndex = TCL_INDEX_NONE;
    nb->notebook.activeIndex = -1;
    if (current == srcIndex) {
	nb->notebook.currentIndex = destIndex;
    } else if (destIndex + 1 <= current + 1 && current + 1 < srcIndex + 1) {
    } else if (destIndex <= current && current < srcIndex) {
	++nb->notebook.currentIndex;
    } else if (srcIndex + 1 < current + 1 && current + 1 <= destIndex + 1) {
    } 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;
    TkSizeT index;
    int index;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab");
	return TCL_ERROR;
    }

    if (GetTabIndex(interp, nb, objv[2], &index) != TCL_OK) {
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
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







-
+















-
-
-
-
+
+
+
+















-
+















-
+



















-
-
+
+
+














-
+







+
+
+
+
+
+
+
+
+

-
+
-
-
+















-
+






-
+



















-
+







/* $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;
    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_ContentData(nb->notebook.mgr, index);
    tab->state = TAB_STATE_HIDDEN;
    if (index == nb->notebook.currentIndex) {
	SelectNearestTab(nb);
    }

    TtkRedisplayWidget(&nb->core);

    } else {
        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;
    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_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) {
    if (tabIndex >= 0) {
	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));
	    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;
    TkSizeT index;
    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_NumberContent(nb->notebook.mgr);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(nContent));
	return TCL_OK;
    }

    status = FindTabIndex(interp, nb, objv[2], &index);
	if (status == TCL_OK) {
    if (status == TCL_OK && index >= 0) {
	if (index != TCL_INDEX_NONE)
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	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 != TCL_INDEX_NONE) {
	if (nb->notebook.currentIndex >= 0) {
	    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 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;
    int i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    result = Tcl_NewListObj(0, NULL);
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205
1206
1207
1208
1209
1210
1209
1210
1211
1212
1213
1214
1215

1216
1217
1218
1219
1220
1221
1222
1223







-
+







/* $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;
    int index;
    Tk_Window window;
    Tab *tab;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "tab ?-option ?value??...");
	return TCL_ERROR;
    }
1267
1268
1269
1270
1271
1272
1273
1274
1275


1276
1277
1278
1279
1280
1281
1282
1280
1281
1282
1283
1284
1285
1286


1287
1288
1289
1290
1291
1292
1293
1294
1295







-
-
+
+








    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.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);
}
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
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







-
-
+
+













-
+








-
+







	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;
    int nContent = Ttk_NumberContent(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 != TCL_INDEX_NONE) {
    if (nb->notebook.currentIndex >= 0) {
	DisplayTab(nb, nb->notebook.currentIndex, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget specification and layout definitions.
 */

static const WidgetSpec NotebookWidgetSpec =
static WidgetSpec NotebookWidgetSpec =
{
    "TNotebook",		/* className */
    sizeof(Notebook),		/* recordSize */
    NotebookOptionSpecs,	/* optionSpecs */
    NotebookCommands,		/* subcommands */
    NotebookInitialize,		/* initializeProc */
    NotebookCleanup,		/* cleanupProc */
1408
1409
1410
1411
1412
1413
1414
1415
1416


1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1421
1422
1423
1424
1425
1426
1427


1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439







-
-
+
+










		TTK_NODE("Notebook.label", TTK_PACK_TOP))))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkNotebook_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkNotebook_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(themePtr, "Tab", TabLayout);
    Ttk_RegisterLayout(themePtr, "TNotebook", NotebookLayout);

    RegisterWidget(interp, "ttk::notebook", &NotebookWidgetSpec);
}

/*EOF*/
Changes to generic/ttk/ttkPanedwindow.c.
70
71
72
73
74
75
76
77

78
79
80


81
82

83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104


105
106
107
108
109
110
111
70
71
72
73
74
75
76

77
78


79
80
81

82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102


103
104
105
106
107
108
109
110
111







-
+

-
-
+
+

-
+


-
+















-
+

-
-
+
+







typedef struct {
    WidgetCore	core;
    PanedPart	paned;
} Paned;

/* @@@ NOTE: -orient is readonly 'cause dynamic oriention changes NYI
 */
static const Tk_OptionSpec PanedOptionSpecs[] = {
static 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_Offset(Paned,paned.orientObj), Tk_Offset(Paned,paned.orient),
	0, ttkOrientStrings, READONLY_OPTION|STYLE_CHANGED },
    {TK_OPTION_INT, "-width", "width", "Width", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.width),
	-1,Tk_Offset(Paned,paned.width),
	0, 0, GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-height", "height", "Height", "0",
	TCL_INDEX_NONE, offsetof(Paned, paned.height),
	-1,Tk_Offset(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[] = {
static 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}
	-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 window)
{
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157







-
+







    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,
    if (Tk_SetOptions(interp, (void*)pane, pw->paned.paneOptionTable,
	    objc, objv, window, &savedOptions, &mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* Sanity-check:
     */
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216







-
+







    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)
static int ShoveDown(Paned *pw, int 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 {
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285







-
+







 * 	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;
    int 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;
    }
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382







-
+







 */
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;
    int 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) {
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421

422
423
424
425
426
427
428
429







-
+















-
+







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)
static void PaneRemoved(void *managerData, int 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) {
    if (Ttk_ContentIndex(pw->paned.mgr, window) >= 0) {
	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);
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
441
442
443
444
445
446
447

448
449
450
451
452
453
454
455







-
+








/* 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)
static int PaneRequest(void *managerData, int 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)) {
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
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







-
-
-
-
-
-


+
+
+
+
+
+
+
+









-
+







    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.
 * This was originally introduced because Tk used to discard events with
 * detail field NotifyInferior. The <<EnteredChild>> event was then used
 * to reset the cursor when the pointer crosses from a parent to a child.
 * Since ticket #47d4f29159, LeaveNotify/NotifyInferior are no longer
 * discarded: the <Leave> event will trigger even with NotifyInferior
 * detail field. The generated <<EnteredChild>> is nevertheless kept for
 * backwards compatibility purpose since it is publicly documented,
 * meaning that someone could bind to it.
 */

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);
	TtkSendVirtualEvent(corePtr->tkwin, "EnteredChild");
    }
}

/*------------------------------------------------------------------------
 * +++ Initialization and cleanup hooks.
 */

602
603
604
605
606
607
608
609

610
611
612
613


614
615
616
617
618
619
620
604
605
606
607
608
609
610

611
612
613


614
615
616
617
618
619
620
621
622







-
+


-
-
+
+







{
    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);
    int i, nSashes = Ttk_NumberContent(pw->paned.mgr) - 1;

    TtkWidgetDisplay(recordPtr, d);
    for (i = 1; i < nContent; ++i) {
	DrawSash(pw, i - 1, d);
    for (i = 0; i < nSashes; ++i) {
	DrawSash(pw, i, d);
    }
}

/*------------------------------------------------------------------------
 * +++ Widget commands.
 */

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
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







-
-
+
+



-
+









+
+
-
+






-
+



-
+
















-
+










-
-







/* $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;
    int nContent = Ttk_NumberContent(pw->paned.mgr);
    int srcIndex, destIndex;
    Tk_Window window;

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 2,objv, "index window ?-option value ...?");
	Tcl_WrongNumArgs(interp, 2,objv, "index slave ?-option value ...?");
	return TCL_ERROR;
    }

    window = Tk_NameToWindow(
	interp, Tcl_GetString(objv[3]), pw->core.tkwin);
    if (!window) {
	return TCL_ERROR;
    }

    if (!strcmp(Tcl_GetString(objv[2]), "end")) {
	destIndex = Ttk_NumberContent(pw->paned.mgr);
    if (TCL_OK != Ttk_GetContentIndexFromObj(
    } else 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: */
    if (srcIndex < 0) { /* New content: */
	return AddPane(interp, pw, destIndex, window, objc-4, objv+4);
    } /* else -- move existing content: */

    if (destIndex + 1 >= nContent + 1)
    if (destIndex >= nContent)
	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;
    int 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 --
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
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







-
-
-
-
+
+
+
+
-










-
+







    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)
    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));
		    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,
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
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







-
+












-
-







/* $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;
    int 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:
809
810
811
812
813
814
815
816

817
818
819
820
821
822
823
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822







-
+







 */
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;
    int i;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    panes = Tcl_NewListObj(0, NULL);
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
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







-
+









-
+

















-
+







    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)) {
    if (sashIndex < 0 || sashIndex >= Ttk_NumberContent(pw->paned.mgr) - 1) {
	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));
	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_NewWideIntObj(pane->sashPos));
    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
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908







-
+







    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */

static const WidgetSpec PanedWidgetSpec =
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
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







-
-
-
+
+
+






-
+







-
+



-
+








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" },
static Ttk_ElementOptionSpec SashElementOptions[] = {
    { "-sashthickness", TK_OPTION_PIXELS,
	    Tk_Offset(SashElement,thicknessObj), "5" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SashElementSize(
    TCL_UNUSED(void *),
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SashElement *sash = (SashElement *)elementRecord;
    int thickness = DEFAULT_SASH_THICKNESS;

    Tcl_GetIntFromObj(NULL, sash->thicknessObj, &thickness);
    Tk_GetPixelsFromObj(NULL, tkwin, sash->thicknessObj, &thickness);
    *widthPtr = *heightPtr = thickness;
}

static const Ttk_ElementSpec SashElementSpec = {
static Ttk_ElementSpec SashElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SashElement),
    SashElementOptions,
    SashElementSize,
    TtkNullElementDraw
};

965
966
967
968
969
970
971

972
973


974
975
976
977
978
979
980
981
982
983
984
985
964
965
966
967
968
969
970
971


972
973
974
975
976
977
978
979
980
981
982
983
984
985







+
-
-
+
+












TTK_BEGIN_LAYOUT(VerticalSashLayout)
    TTK_NODE("Sash.vsash", TTK_FILL_Y)
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Registration routine.
 */

MODULE_SCOPE
void TtkPanedwindow_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkPanedwindow_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);
    RegisterWidget(interp, "ttk::panedwindow", &PanedWidgetSpec);

    Ttk_RegisterElement(interp, themePtr, "hsash", &SashElementSpec, 0);
    Ttk_RegisterElement(interp, themePtr, "vsash", &SashElementSpec, 0);

    Ttk_RegisterLayout(themePtr, "TPanedwindow", PanedLayout);
    Ttk_RegisterLayout(themePtr, "Horizontal.Sash", HorizontalSashLayout);
    Ttk_RegisterLayout(themePtr, "Vertical.Sash", VerticalSashLayout);
}

Changes to generic/ttk/ttkProgress.c.
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33


34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61

62
63
64


65
66

67
68
69
70
71
72
73
74



75
76
77
78
79


80
81
82


83

84
85

86
87
88
89



90
91
92
93
94
95
96
97
98
99
17
18
19
20
21
22
23


24


25

26



27
28
29

30

31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46









47



48
49
50

51
52



53



54
55
56





57
58
59


60
61

62
63

64
65



66
67
68



69
70
71
72
73
74
75







-
-
+
-
-

-

-
-
-
+
+

-
+
-














-
+

-
-
-
-
-
-
-
-
-
+
-
-
-
+
+

-
+

-
-
-

-
-
-
+
+
+
-
-
-
-
-
+
+

-
-
+
+
-
+

-
+

-
-
-
+
+
+
-
-
-







    TTK_PROGRESSBAR_DETERMINATE, TTK_PROGRESSBAR_INDETERMINATE
};
static const char *const ProgressbarModeStrings[] = {
    "determinate", "indeterminate", NULL
};

typedef struct {
    Tcl_Obj 	*anchorObj;
    Tcl_Obj 	*fontObj;
    Tcl_Obj 	*orientObj;
    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 	*variableObj;
    Tcl_Obj 	*maximumObj;
    Tcl_Obj 	*valueObj;
    Tcl_Obj 	*variableObj;
    Tcl_Obj 	*phaseObj;
    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[] =
static 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_STRING_TABLE, "-orient", "orient", "Orient",
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	"left", offsetof(Progressbar,progress.justifyObj), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },
	"horizontal", Tk_Offset(Progressbar,progress.orientObj), -1,
	0, ttkOrientStrings, STYLE_CHANGED },
    {TK_OPTION_PIXELS, "-length", "length", "Length",
        DEF_PROGRESSBAR_LENGTH, offsetof(Progressbar,progress.lengthObj), TCL_INDEX_NONE,
        DEF_PROGRESSBAR_LENGTH, Tk_Offset(Progressbar,progress.lengthObj), -1,
	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_Offset(Progressbar,progress.modeObj),
	Tk_Offset(Progressbar,progress.mode),
	0, 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,
    {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum",
	"100", Tk_Offset(Progressbar,progress.maximumObj), -1,
	0, 0, 0 },
    {TK_OPTION_STRING, "-text", "text", "Text", "",
	offsetof(Progressbar,progress.textObj), TCL_INDEX_NONE,
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	NULL, Tk_Offset(Progressbar,progress.variableObj), -1,
	0,0,GEOMETRY_CHANGED },
	TK_OPTION_NULL_OK, 0, 0 },
    {TK_OPTION_DOUBLE, "-value", "value", "Value",
	"0.0", offsetof(Progressbar,progress.valueObj), TCL_INDEX_NONE,
	"0.0", Tk_Offset(Progressbar,progress.valueObj), -1,
	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_INT, "-phase", "phase", "Phase",
	"0", Tk_Offset(Progressbar,progress.phaseObj), -1,
	0, 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:
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135

136
137
138



139
140

141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
92
93
94
95
96
97
98

99
100
101
102
103

104
105
106
107
108
109
110
111
112


113
114
115
116

117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132







-
+




-







+

-
-
+
+
+

-
+





+


-







}

/* 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)
static void AnimateProgressProc(void *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;
	if (phase > pb->progress.maxPhase) {
	    phase = 0;
	}
	Tcl_DecrRefCount(pb->progress.phaseObj);
	pb->progress.phaseObj = Tcl_NewWideIntObj(phase);
	pb->progress.phaseObj = Tcl_NewIntObj(phase);
	Tcl_IncrRefCount(pb->progress.phaseObj);

	/*
	 * Reschedule:
	 */

	pb->progress.timer = Tcl_CreateTimerHandler(
	    pb->progress.period, AnimateProgressProc, clientData);

	TtkRedisplayWidget(&pb->core);
    }
}

/* CheckAnimation --
 * 	If animation is enabled and not scheduled, schedule it.
 * 	If animation is disabled but scheduled, cancel it.
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305

306
307
308
309
310
311
312
268
269
270
271
272
273
274

275
276
277
278
279
280
281

282
283
284
285
286
287
288
289







-
+






-
+







 * 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;
    int 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);
    Ttk_GetOrientFromObj(NULL, pb->progress.orientObj, &orient);

    if (orient == TTK_ORIENT_HORIZONTAL) {
	*widthPtr = length;
    } else {
	*heightPtr = length;
    }

362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362







-
+








-
+








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;
    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);
    TtkGetOrientFromObj(NULL, pb->progress.orientObj, &orient);
    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(
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
461
462
463
464
465
466
467

468
469
470
471
472
473
474
475







-
+







    Tcl_Obj *prefix[2];
    int status;

    /* ASSERT: objc >= 2 */

    prefix[0] = Tcl_NewStringObj(cmdName, -1);
    prefix[1] = objv[0];
    Tcl_ListObjReplace(interp, cmd, 0,2, 2,prefix);
    Tcl_ListObjReplace(interp, cmd, 0, 2, 2,prefix);

    Tcl_IncrRefCount(cmd);
    status = Tcl_EvalObjEx(interp, cmd, 0);
    Tcl_DecrRefCount(cmd);

    return status;
}
528
529
530
531
532
533
534
535

536
537
538
539
540
541
542
505
506
507
508
509
510
511

512
513
514
515
516
517
518
519







-
+







    { "stop", 		ProgressbarStopCommand,0 },
    { 0,0,0 }
};

/*
 * Widget specification:
 */
static const WidgetSpec ProgressbarWidgetSpec =
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
570


571
572
573
574
575
576
577
578
579
580
581
582
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







-
+
-






-
-
+
+












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.pbar", TTK_PACK_LEFT|TTK_FILL_Y))
	TTK_NODE("Horizontal.Progressbar.text", TTK_PACK_LEFT))
TTK_END_LAYOUT

/*
 * Initialization:
 */

MODULE_SCOPE
void TtkProgressbar_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkProgressbar_Init(Tcl_Interp *interp)
{
    Ttk_Theme themePtr = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(themePtr,
	"Vertical.TProgressbar", VerticalProgressbarLayout);
    Ttk_RegisterLayout(themePtr,
	"Horizontal.TProgressbar", HorizontalProgressbarLayout);

    RegisterWidget(interp, "ttk::progressbar", &ProgressbarWidgetSpec);
}

/*EOF*/
Changes to generic/ttk/ttkScale.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7

8
9
10
11
12
13
14







-







/*
 * 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))
47
48
49
50
51
52
53
54

55
56
57

58
59
60

61
62
63
64
65



66
67
68

69
70

71
72

73
74

75
76
77
78

79
80
81
82
83
84
85
46
47
48
49
50
51
52

53
54
55

56
57
58

59
60
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
{
    WidgetCore core;
    ScalePart  scale;
} Scale;

static const Tk_OptionSpec ScaleOptionSpecs[] =
static Tk_OptionSpec ScaleOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scale,scale.commandObj), TCL_INDEX_NONE,
	Tk_Offset(Scale,scale.commandObj), -1,
	TK_OPTION_NULL_OK,0,0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable", "",
	offsetof(Scale,scale.variableObj), TCL_INDEX_NONE,
	Tk_Offset(Scale,scale.variableObj), -1,
	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_Offset(Scale,scale.orientObj),
	Tk_Offset(Scale,scale.orient),
	0, ttkOrientStrings, STYLE_CHANGED },

    {TK_OPTION_DOUBLE, "-from", "from", "From", "0",
	offsetof(Scale,scale.fromObj), TCL_INDEX_NONE, 0, 0, 0},
	Tk_Offset(Scale,scale.fromObj), -1, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To", "1.0",
	offsetof(Scale,scale.toObj), TCL_INDEX_NONE, 0, 0, 0},
	Tk_Offset(Scale,scale.toObj), -1, 0, 0, 0},
    {TK_OPTION_DOUBLE, "-value", "value", "Value", "0",
	offsetof(Scale,scale.valueObj), TCL_INDEX_NONE, 0, 0, 0},
	Tk_Offset(Scale,scale.valueObj), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-length", "length", "Length",
	DEF_SCALE_LENGTH, offsetof(Scale,scale.lengthObj), TCL_INDEX_NONE, 0, 0,
	DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0,
    	GEOMETRY_CHANGED},

    {TK_OPTION_STRING, "-state", "state", "State",
	"normal", offsetof(Scale,scale.stateObj), TCL_INDEX_NONE,
	"normal", Tk_Offset(Scale,scale.stateObj), -1,
        0, 0, STATE_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

static XPoint ValueToPoint(Scale *scalePtr, double value);
374
375
376
377
378
379
380
381
382


383
384
385
386
387
388
389
373
374
375
376
377
378
379


380
381
382
383
384
385
386
387
388







-
-
+
+







    } 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);
	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)
{
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
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







-
+
















+
+
-
-
+
+



+
+
-
-
+
+





+
-
-
+
+









    { "identify",    TtkWidgetIdentifyCommand,0 },
    { "set",         ScaleSetCommand,0 },
    { "get",         ScaleGetCommand,0 },
    { "coords",      ScaleCoordsCommand,0 },
    { 0,0,0 }
};

static const WidgetSpec ScaleWidgetSpec =
static WidgetSpec ScaleWidgetSpec =
{
    "TScale",			/* Class name */
    sizeof(Scale),		/* record size */
    ScaleOptionSpecs,		/* option specs */
    ScaleCommands,		/* widget commands */
    ScaleInitialize,		/* initialization proc */
    ScaleCleanup,		/* cleanup proc */
    ScaleConfigure,		/* configure proc */
    ScalePostConfigure,		/* postConfigure */
    ScaleGetLayout, 		/* getLayoutProc */
    ScaleSize,			/* sizeProc */
    ScaleDoLayout,		/* layoutProc */
    TtkWidgetDisplay		/* displayProc */
};

TTK_BEGIN_LAYOUT(VerticalScaleLayout)
    TTK_GROUP("Vertical.Scale.focus", TTK_FILL_BOTH,
	TTK_GROUP("Vertical.Scale.padding", TTK_FILL_BOTH,
    TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH,
	TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) )
	    TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH,
		TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP))))
TTK_END_LAYOUT

TTK_BEGIN_LAYOUT(HorizontalScaleLayout)
    TTK_GROUP("Horizontal.Scale.focus", TTK_FILL_BOTH,
	TTK_GROUP("Horizontal.Scale.padding", TTK_FILL_BOTH,
    TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
	TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) )
	    TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH,
		TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT))))
TTK_END_LAYOUT

/*
 * Initialization.
 */

MODULE_SCOPE
void TtkScale_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkScale_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "Vertical.TScale", VerticalScaleLayout);
    Ttk_RegisterLayout(theme, "Horizontal.TScale", HorizontalScaleLayout);

    RegisterWidget(interp, "ttk::scale", &ScaleWidgetSpec);
}

Changes to generic/ttk/ttkScroll.c.
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65







-
+







};

/* TtkCreateScrollHandle --
 * 	Initialize scroll handle.
 */
ScrollHandle TtkCreateScrollHandle(WidgetCore *corePtr, Scrollable *scrollPtr)
{
    ScrollHandle h = (ScrollHandle)ckalloc(sizeof(*h));
    ScrollHandle h = ckalloc(sizeof(*h));

    h->flags = 0;
    h->corePtr = corePtr;
    h->scrollPtr = scrollPtr;

    scrollPtr->first = 0;
    scrollPtr->last = 1;
126
127
128
129
130
131
132
133

134
135
136
137
138

139
140
141
142
143
144
145
126
127
128
129
130
131
132

133
134
135
136
137

138
139
140
141
142
143
144
145







-
+




-
+







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);
    Tcl_Preserve((ClientData) interp);
    code = UpdateScrollbar(interp, h);
    if (code == TCL_ERROR && !Tcl_InterpDeleted(interp)) {
	Tcl_BackgroundException(interp, code);
    }
    Tcl_Release(interp);
    Tcl_Release((ClientData) interp);
}

/* TtkScrolled --
 * 	Update scroll info, schedule scrollbar update.
 */
void TtkScrolled(ScrollHandle h, int first, int last, int total)
{
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







-
+







	    || (h->flags & SCROLL_UPDATE_REQUIRED))
    {
	s->first = first;
	s->last = last;
	s->total = total;

	if (!(h->flags & SCROLL_UPDATE_PENDING)) {
	    Tcl_DoWhenIdle(UpdateScrollbarBG, h);
	    Tcl_DoWhenIdle(UpdateScrollbarBG, (ClientData)h);
	    h->flags |= SCROLL_UPDATE_PENDING;
	}
    }
}

/* TtkScrollbarUpdateRequired --
 * 	Force a scrollbar update at the next call to TtkScrolled(),
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244


245
246
247
248
249
250
251
225
226
227
228
229
230
231


232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251







-
-











+
+







	    return TCL_ERROR;
	}
    } else {
	double fraction;
	int count;

	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
	    case TK_SCROLL_ERROR:
		return TCL_ERROR;
	    case TK_SCROLL_MOVETO:
		newFirst = (int) ((fraction * s->total) + 0.5);
		break;
	    case TK_SCROLL_UNITS:
		newFirst = s->first + count;
		break;
	    case TK_SCROLL_PAGES: {
		int perPage = s->last - s->first;	/* @@@ */
		newFirst = s->first + count * perPage;
		break;
	    }
	    default:
		return TCL_ERROR;
	}
    }

    TtkScrollTo(h, newFirst, 0);

    return TCL_OK;
}
270
271
272
273
274
275
276
277

278
279
280
281
270
271
272
273
274
275
276

277
278
279
280
281







-
+




	TtkRedisplayWidget(h->corePtr);
    }
}

void TtkFreeScrollHandle(ScrollHandle h)
{
    if (h->flags & SCROLL_UPDATE_PENDING) {
	Tcl_CancelIdleCall(UpdateScrollbarBG, h);
	Tcl_CancelIdleCall(UpdateScrollbarBG, (ClientData)h);
    }
    ckfree(h);
}

Changes to generic/ttk/ttkScrollbar.c.
27
28
29
30
31
32
33
34

35
36
37

38
39
40
41
42



43
44
45
46
47
48
49
27
28
29
30
31
32
33

34
35
36

37
38
39



40
41
42
43
44
45
46
47
48
49







-
+


-
+


-
-
-
+
+
+








typedef struct
{
    WidgetCore core;
    ScrollbarPart scrollbar;
} Scrollbar;

static const Tk_OptionSpec ScrollbarOptionSpecs[] =
static Tk_OptionSpec ScrollbarOptionSpecs[] =
{
    {TK_OPTION_STRING, "-command", "command", "Command", "",
	offsetof(Scrollbar, scrollbar.commandObj), TCL_INDEX_NONE, 0, 0, 0},
	Tk_Offset(Scrollbar,scrollbar.commandObj), -1, 0, 0, 0},

    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "vertical",
	offsetof(Scrollbar, scrollbar.orientObj),
	offsetof(Scrollbar, scrollbar.orient),
	0, (void *)ttkOrientStrings, STYLE_CHANGED },
	Tk_Offset(Scrollbar,scrollbar.orientObj),
	Tk_Offset(Scrollbar,scrollbar.orient),
	0, ttkOrientStrings, STYLE_CHANGED },

    WIDGET_TAKEFOCUS_FALSE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
 * +++ Widget hooks.
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307







-
+







    { "state",  	TtkWidgetStateCommand,0 },
    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget specification.
 */
static const WidgetSpec ScrollbarWidgetSpec =
static WidgetSpec ScrollbarWidgetSpec =
{
    "TScrollbar",		/* className */
    sizeof(Scrollbar),		/* recordSize */
    ScrollbarOptionSpecs,	/* optionSpecs */
    ScrollbarCommands,		/* subcommands */
    ScrollbarInitialize,	/* initializeProc */
    TtkNullCleanup,		/* cleanupProc */
327
328
329
330
331
332
333
334
335


336
337
338
339
340
341
342
343
344
345
327
328
329
330
331
332
333


334
335
336
337
338
339
340
341
342
343
344
345







-
-
+
+










	TTK_NODE("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH))
TTK_END_LAYOUT

/*------------------------------------------------------------------------
 * +++ Initialization.
 */

MODULE_SCOPE
void TtkScrollbar_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkScrollbar_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme,"Vertical.TScrollbar",VerticalScrollbarLayout);
    Ttk_RegisterLayout(theme,"Horizontal.TScrollbar",HorizontalScrollbarLayout);

    RegisterWidget(interp, "ttk::scrollbar", &ScrollbarWidgetSpec);
}

/*EOF*/
Changes to generic/ttk/ttkSeparator.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
18
19
20
21
22
23
24

25
26



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69







-
+

-
-
-
+
+
+












-
+



















-
+








typedef struct
{
    WidgetCore core;
    SeparatorPart separator;
} Separator;

static const Tk_OptionSpec SeparatorOptionSpecs[] = {
static Tk_OptionSpec SeparatorOptionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal",
	offsetof(Separator,separator.orientObj),
	offsetof(Separator,separator.orient),
	0, (void *)ttkOrientStrings, STYLE_CHANGED },
	Tk_Offset(Separator,separator.orientObj),
	Tk_Offset(Separator,separator.orient),
	0, 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;
    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 const WidgetSpec SeparatorWidgetSpec =
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
79
80
81
82
83
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[] = {
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 const WidgetSpec SizegripWidgetSpec =
static WidgetSpec SizegripWidgetSpec =
{
    "TSizegrip",		/* className */
    sizeof(WidgetCore),		/* recordSize */
    SizegripOptionSpecs, 	/* optionSpecs */
    SizegripCommands,		/* subcommands */
    TtkNullInitialize,		/* initializeProc */
    TtkNullCleanup,		/* cleanupProc */
116
117
118
119
120
121
122
123
124


125
126
127
128
129
130
131
132
133
134
135
116
117
118
119
120
121
122


123
124
125
126
127
128
129
130
131
132
133
134
135







-
-
+
+











TTK_BEGIN_LAYOUT(SizegripLayout)
    TTK_NODE("Sizegrip.sizegrip", TTK_PACK_BOTTOM|TTK_STICK_S|TTK_STICK_E)
TTK_END_LAYOUT

/* +++ Initialization:
 */

MODULE_SCOPE
void TtkSeparator_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkSeparator_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    Ttk_RegisterLayout(theme, "TSeparator", SeparatorLayout);
    Ttk_RegisterLayout(theme, "TSizegrip", SizegripLayout);

    RegisterWidget(interp, "ttk::separator", &SeparatorWidgetSpec);
    RegisterWidget(interp, "ttk::sizegrip", &SizegripWidgetSpec);
}

/*EOF*/
Changes to generic/ttk/ttkSquare.c.
44
45
46
47
48
49
50
51

52
53
54

55
56
57
58


59
60
61

62
63
64

65
66
67
68

69
70
71
72

73
74
75

76
77
78
79
80
81
82
44
45
46
47
48
49
50

51
52
53

54
55
56


57
58
59
60

61
62
63

64
65
66
67

68
69
70
71

72
73
74

75
76
77
78
79
80
81
82







-
+


-
+


-
-
+
+


-
+


-
+



-
+



-
+


-
+







 * 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[] =
static Tk_OptionSpec SquareOptionSpecs[] =
{
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
     DEFAULT_BORDERWIDTH, offsetof(Square,square.borderWidthObj), TCL_INDEX_NONE,
     DEFAULT_BORDERWIDTH, Tk_Offset(Square,square.borderWidthObj), -1,
     0,0,GEOMETRY_CHANGED },
    {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground",
     DEFAULT_BACKGROUND, offsetof(Square,square.foregroundObj),
     TCL_INDEX_NONE, 0, 0, 0},
     DEFAULT_BACKGROUND, Tk_Offset(Square,square.foregroundObj),
     -1, 0, 0, 0},

    {TK_OPTION_PIXELS, "-width", "width", "Width",
     "50", offsetof(Square,square.widthObj), TCL_INDEX_NONE, 0, 0,
     "50", Tk_Offset(Square,square.widthObj), -1, 0, 0,
     GEOMETRY_CHANGED},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
     "50", offsetof(Square,square.heightObj), TCL_INDEX_NONE, 0, 0,
     "50", Tk_Offset(Square,square.heightObj), -1, 0, 0,
     GEOMETRY_CHANGED},

    {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL,
     offsetof(Square,square.paddingObj), TCL_INDEX_NONE,
     Tk_Offset(Square,square.paddingObj), -1,
     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},
     NULL, Tk_Offset(Square,square.reliefObj), -1, 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},
     "center", Tk_Offset(Square,square.anchorObj), -1, 0, 0, 0},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*
 * Almost all of the widget functionality is handled by the default Ttk
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153







-
+








/*
 * 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 =
static WidgetSpec SquareWidgetSpec =
{
    "TSquare",			/* className */
    sizeof(Square),		/* recordSize */
    SquareOptionSpecs,		/* optionSpecs */
    SquareCommands,		/* subcommands */
    TtkNullInitialize,		/* initializeProc */
    TtkNullCleanup,		/* cleanupProc */
172
173
174
175
176
177
178
179

180
181

182
183

184
185

186
187

188
189
190


191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227

228
229
230
231
232
233
234

235
236
237
238
239
240
241

242
243
244
245
246
247
248
172
173
174
175
176
177
178

179
180

181
182

183
184

185
186

187
188


189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221

222
223
224
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_Obj *foregroundObj;
    Tcl_Obj *borderWidthObj;
    Tcl_Obj *reliefObj;
    Tcl_Obj *widthObj;
    Tcl_Obj *heightObj;
} SquareElement;

static const Ttk_ElementOptionSpec SquareElementOptions[] =
static Ttk_ElementOptionSpec SquareElementOptions[] =
{
    { "-background", TK_OPTION_BORDER, offsetof(SquareElement,borderObj),
    { "-background", TK_OPTION_BORDER, Tk_Offset(SquareElement,borderObj),
    	DEFAULT_BACKGROUND },
    { "-foreground", TK_OPTION_BORDER, offsetof(SquareElement,foregroundObj),
    { "-foreground", TK_OPTION_BORDER, Tk_Offset(SquareElement,foregroundObj),
    	DEFAULT_BACKGROUND },
    { "-borderwidth", TK_OPTION_PIXELS, offsetof(SquareElement,borderWidthObj),
    { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(SquareElement,borderWidthObj),
    	DEFAULT_BORDERWIDTH },
    { "-relief", TK_OPTION_RELIEF, offsetof(SquareElement,reliefObj),
    { "-relief", TK_OPTION_RELIEF, Tk_Offset(SquareElement,reliefObj),
    	"raised" },
    { "-width",  TK_OPTION_PIXELS, offsetof(SquareElement,widthObj), "20"},
    { "-height", TK_OPTION_PIXELS, offsetof(SquareElement,heightObj), "20"},
    { "-width",  TK_OPTION_PIXELS, Tk_Offset(SquareElement,widthObj), "20"},
    { "-height", TK_OPTION_PIXELS, Tk_Offset(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 *),
    TCL_UNUSED(void *), /* clientData */
    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);
    Tk_GetPixelsFromObj(NULL, tkwin, 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 *),
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(unsigned int))
    TCL_UNUSED(Ttk_State))
{
    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_GetPixelsFromObj(NULL, tkwin, 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 =
static Ttk_ElementSpec SquareElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(SquareElement),
    SquareElementOptions,
    SquareElementSize,
    SquareElementDraw
};
Changes to generic/ttk/ttkState.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
1
2
3
4
5
6
7
8
9
10
11

12

13

14











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







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48


49
50
51
52
53
54
55

56
57
58
59
60
61
62
63











-
+
-

-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+














-
-







-
+







/*
 * 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_*
 * Table of state names.
 * #defines in ttkTheme.h.
 */
static const char *const stateNames[] =
static const struct {
{
    "active",		/* Mouse cursor is over widget or element */
    "disabled",		/* Widget is disabled */
    "focus",		/* Widget has keyboard focus */
    "pressed",		/* Pressed or "armed" */
    "selected",		/* "on", "true", "current", etc. */
    "background",	/* Top-level window lost focus (Mac,Win "inactive") */
    "alternate",	/* Widget-specific alternate display style */
    "invalid",		/* Bad value */
    "readonly",		/* Editing/modification disabled */
    "hover",		/* Mouse cursor is over widget */
    char name[12];
    int value;
} stateNames[] = {
    {"active", TTK_STATE_ACTIVE},		/* Mouse cursor is over widget or element */
    {"disabled", TTK_STATE_DISABLED},		/* Widget is disabled */
    {"focus", TTK_STATE_FOCUS},		/* Widget has keyboard focus */
    {"pressed", TTK_STATE_PRESSED},		/* Pressed or "armed" */
    {"selected", TTK_STATE_SELECTED},		/* "on", "true", "current", etc. */
    {"background", TTK_STATE_BACKGROUND},	/* Top-level window lost focus (Mac,Win "inactive") */
    {"alternate", TTK_STATE_ALTERNATE},	/* Widget-specific alternate display style */
    {"invalid", TTK_STATE_INVALID},		/* Bad value */
    {"readonly", TTK_STATE_READONLY},		/* Editing/modification disabled */
    {"hover", TTK_STATE_HOVER},		/* Mouse cursor is over widget */
    "reserved1",	/* Reserved for future extension */
    "reserved2",	/* Reserved for future extension */
    "reserved3",	/* Reserved for future extension */
    "user3",		/* User-definable state */
    "user2",		/* User-definable state */
    "user1",		/* User-definable state */
    NULL
    {"user6", TTK_STATE_USER6},		/* User-definable state */
    {"user5", TTK_STATE_USER5},		/* User-definable state */
    {"user4", TTK_STATE_USER4},		/* User-definable state */
    {"user3", TTK_STATE_USER3},		/* User-definable state */
    {"user2", TTK_STATE_USER2},		/* User-definable state */
    {"user1", TTK_STATE_USER1},		/* User-definable state */
    {"", 0}
};

/*------------------------------------------------------------------------
 * +++ StateSpec object type:
 *
 * The string representation consists of a list of state names,
 * each optionally prefixed by an exclamation point (!).
 *
 * The internal representation uses the upper half of the longValue
 * to store the on bits and the lower half to store the off bits.
 * If we ever get more than 16 states, this will need to be reconsidered...
 */

static int  StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj);
/* static void StateSpecFreeIntRep(Tcl_Obj *); */
#define StateSpecFreeIntRep 0		/* not needed */
static void StateSpecDupIntRep(Tcl_Obj *, Tcl_Obj *);
static void StateSpecUpdateString(Tcl_Obj *);

static
struct Tcl_ObjType StateSpecObjType =
{
    "StateSpec",
    StateSpecFreeIntRep,
    0,
    StateSpecDupIntRep,
    StateSpecUpdateString,
    StateSpecSetFromAny
};

static void StateSpecDupIntRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr)
{
85
86
87
88
89
90
91
92
93


94
95
96
97

98
99
100
101
102
103
104
105
106
107

108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138



139

140

141
142
143
144
145
146
147
84
85
86
87
88
89
90


91
92
93
94
95

96
97
98
99
100
101
102
103
104
105

106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134



135
136
137
138
139

140
141
142
143
144
145
146
147







-
-
+
+



-
+









-
+

-
+

















-
+








-
-
-
+
+
+

+
-
+







	if (*stateName == '!') {
	    ++stateName;
	    on = 0;
	} else {
	    on = 1;
	}

	for (j = 0; stateNames[j] != 0; ++j) {
	    if (strcmp(stateName, stateNames[j]) == 0)
	for (j = 0; stateNames[j].value; ++j) {
	    if (strcmp(stateName, stateNames[j].name) == 0)
		break;
	}

    	if (stateNames[j] == 0) {
    	if (stateNames[j].value == 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);
	    onbits |= stateNames[j].value;
	} else {
	    offbits |= (1<<j);
	    offbits |= stateNames[j].value;
	}
    }

    /* Invalidate old intrep:
     */
    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &StateSpecObjType;
    objPtr->internalRep.longValue = (onbits << 16) | offbits;

    return TCL_OK;
}

static void StateSpecUpdateString(Tcl_Obj *objPtr)
{
    unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    unsigned int onbits = objPtr->internalRep.longValue >> 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))
    for (i=0; stateNames[i].value; ++i) {
	if (mask & stateNames[i].value) {
	    if (offbits & stateNames[i].value) {
		Tcl_DStringAppend(&result, "!", 1);
	    }
	    Tcl_DStringAppend(&result, stateNames[i], -1);
	    Tcl_DStringAppend(&result, stateNames[i].name, -1);
	    Tcl_DStringAppend(&result, " ", 1);
	}
    }

    len = Tcl_DStringLength(&result);
    if (len) {
	/* 'len' includes extra trailing ' ' */
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204


205
206
207
208
209
210
211
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202


203
204
205
206
207
208
209
210
211







-
+


















-
-
+
+







{
    if (objPtr->typePtr != &StateSpecObjType) {
	int status = StateSpecSetFromAny(interp, objPtr);
	if (status != TCL_OK)
	    return status;
    }

    spec->onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    spec->onbits = objPtr->internalRep.longValue >> 16;
    spec->offbits = objPtr->internalRep.longValue & 0x0000FFFF;
    return TCL_OK;
}


/*
 * Tk_StateMapLookup --
 *
 * 	A state map is a paired list of StateSpec / value pairs.
 *	Returns the value corresponding to the first matching state
 *	specification, or NULL if not found or an error occurs.
 */
Tcl_Obj *Ttk_StateMapLookup(
    Tcl_Interp *interp,		/* Where to leave error messages; may be NULL */
    Ttk_StateMap map,		/* State map */
    Ttk_State state)    	/* State to look up */
{
    Tcl_Obj **specs;
    int nSpecs;
    int j, status;
    int j, nSpecs;
    int status;

    status = Tcl_ListObjGetElements(interp, map, &nSpecs, &specs);
    if (status != TCL_OK)
	return NULL;

    for (j = 0; j < nSpecs; j += 2) {
	Ttk_StateSpec spec;
228
229
230
231
232
233
234
235
236


237
238
239
240
241
242
243
228
229
230
231
232
233
234


235
236
237
238
239
240
241
242
243







-
-
+
+







 * 	this basically just checks for errors.
 */
Ttk_StateMap Ttk_GetStateMapFromObj(
    Tcl_Interp *interp,		/* Where to leave error messages; may be NULL */
    Tcl_Obj *mapObj)		/* State map */
{
    Tcl_Obj **specs;
    int nSpecs;
    int j, status;
    int j, nSpecs;
    int status;

    status = Tcl_ListObjGetElements(interp, mapObj, &nSpecs, &specs);
    if (status != TCL_OK)
	return NULL;

    if (nSpecs % 2 != 0) {
	if (interp) {
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272
273
274
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274







-
+










    return mapObj;
}

/*
 * Ttk_StateTableLooup --
 * 	Look up an index from a statically allocated state table.
 */
int Ttk_StateTableLookup(const Ttk_StateTable *map, unsigned int state)
int Ttk_StateTableLookup(Ttk_StateTable *map, Ttk_State 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
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 "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,
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30







+














-
+







/*
 * 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_OptionSpec	*optionSpecs;	/* ... */
    Tk_OptionTable	optionTable;	/* ... */
    int         	recordSize;	/* size of tag record */
    int 		nTags;		/* #tags defined so far */
    Tcl_HashTable	tags;		/* defined tags */
};

/*------------------------------------------------------------------------
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64







-
+








/*------------------------------------------------------------------------
 * +++ Tag tables.
 */

Ttk_TagTable Ttk_CreateTagTable(
    Tcl_Interp *interp, Tk_Window tkwin,
    const Tk_OptionSpec *optionSpecs, int recordSize)
    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;
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
77
78
79
80
81
82
83











84
85
86
87
88
89
90







-
-
-
-
-
-
-
-
-
-
-







	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) {
276
277
278
279
280
281
282
283
284


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302
303

304
305
306
307
308
309
310
311
312
313
314
266
267
268
269
270
271
272


273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291
292

293
294
295
296
297
298
299
300
301
302
303
304







-
-
+
+















-
+


-
+











{
    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;
	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)
{
    const Tk_OptionSpec *optionSpec = tagTable->optionSpecs;
    Tk_OptionSpec *optionSpec = tagTable->optionSpecs;

    while (optionSpec->type != TK_OPTION_END) {
	TkSizeT offset = optionSpec->objOffset;
	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.
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+







	style = style->parentStyle;
    }
    return 0;
}

/*
 * Ttk_StyleDefault --
 * 	Look up default resource setting the in the specified style.
 * 	Look up default resource setting 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)
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+







 * +++ 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. */
    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
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) {
    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
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;
	Ttk_ElementOptionSpec *e = elementClass->specPtr->options+i;
	optionMap[i] = TTKGetOptionSpec(e->optionName, optionTable, e->type);
    }

    return optionMap;
}

/* GetOptionMap --
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247







-
+




















-
+








/*
 * 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)
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;
	const char *defaultValue = specPtr->options[i].defaultValue;
	if (defaultValue) {
	    elementClass->defaultValues[i] = Tcl_NewStringObj(defaultValue,-1);
	    Tcl_IncrRefCount(elementClass->defaultValues[i]);
	} else {
	    elementClass->defaultValues[i] = 0;
	}
    }
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
399
400
401
402
403
404
405


406
407
408
409

410
411
412
413
414
415
416
417







418
419
420
421
422
423
424







-
-




-
+







-
-
-
-
-
-
-







    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,
    void *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);
480
481
482
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
471
472
473
474
475
476
477

478
479

480
481
482
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







-
+

-
+




















-
+







 *	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)
    Tcl_Interp *interp, void *clientData, Ttk_CleanupProc *cleanupProc)
{
    StylePackageData *pkgPtr = (StylePackageData *)GetStylePackageData(interp);
    StylePackageData *pkgPtr = GetStylePackageData(interp);
    Cleanup *cleanup = (Cleanup *)ckalloc(sizeof(*cleanup));

    cleanup->clientData = clientData;
    cleanup->cleanupProc = cleanupProc;
    cleanup->next = pkgPtr->cleanupList;
    pkgPtr->cleanupList = cleanup;
}

/* ThemeChangedProc --
 * 	Notify all widgets that the theme has been changed.
 * 	Scheduled as an idle callback; clientData is a StylePackageData *.
 *
 * 	Sends a <<ThemeChanged>> event to every widget in the hierarchy.
 * 	Widgets respond to this by calling the  WorldChanged class proc,
 * 	which in turn recreates the layout.
 *
 * 	The Tk C API doesn't doesn't provide an easy way to traverse
 * 	the widget hierarchy, so this is done by evaluating a Tcl script.
 */

static void ThemeChangedProc(ClientData clientData)
static void ThemeChangedProc(void *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);
526
527
528
529
530
531
532




















533
534
535
536
537
538
539
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







static void ThemeChanged(StylePackageData *pkgPtr)
{
    if (!pkgPtr->themeChangePending) {
	Tcl_DoWhenIdle(ThemeChangedProc, pkgPtr);
	pkgPtr->themeChangePending = 1;
    }
}

/* Ttk_TkDestroyedHandler --
 *	See bug [310c74ecf440]: idle calls to ThemeChangedProc()
 *	need to be canceled when Tk is destroyed, since the interp
 *	may still be active afterward; canceling them from
 *	Ttk_StylePkgFree() would be too late.
 */
void Ttk_TkDestroyedHandler(
    Tcl_Interp* interp)
{
    StylePackageData* pkgPtr = GetStylePackageData(interp);

    /*
     * Cancel any pending ThemeChanged calls. We might be called
     * before Ttk is initialized. See bug [3981091ed336].
     */
    if (pkgPtr && pkgPtr->themeChangePending) {
	Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr);
    }
}

/*
 * Ttk_CreateTheme --
 *	Create a new theme and register it in the global theme table.
 *
 * Returns:
 * 	Pointer to new Theme structure; NULL if named theme already exists.
665
666
667
668
669
670
671
672
673


674
675
676
677
678
679
680
676
677
678
679
680
681
682


683
684
685
686
687
688
689
690
691







-
-
+
+







    return pkgPtr->cache;
}

/*
 * Register a new layout specification with a style.
 * @@@ TODO: Make sure layoutName is not ".", root style must not have a layout
 */
MODULE_SCOPE
void Ttk_RegisterLayoutTemplate(
MODULE_SCOPE void
Ttk_RegisterLayoutTemplate(
    Ttk_Theme theme,			/* Target theme */
    const char *layoutName,		/* Name of new layout */
    Ttk_LayoutTemplate layoutTemplate)	/* Template */
{
    Ttk_Style style = Ttk_GetStyle(theme, layoutName);
    if (style->layoutTemplate) {
	Ttk_FreeLayoutTemplate(style->layoutTemplate);
868
869
870
871
872
873
874
875

876
877
878
879
880
881
882
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893







-
+







 *	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 */
    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) {
909
910
911
912
913
914
915
916

917
918
919
920
921
922
923
920
921
922
923
924
925
926

927
928
929
930
931
932
933
934







-
+







    return elementClass;
}

/* Ttk_RegisterElementSpec (deprecated) --
 * 	Register a new element.
 */
int Ttk_RegisterElementSpec(Ttk_Theme theme,
    const char *name, const Ttk_ElementSpec *specPtr, void *clientData)
    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
984
985
986
987
988
989
990

991
992
993
994
995

996
997
998
999

1000
1001
1002
1003
1004
1005
1006
1007







-
+




-
+



-
+







 * 	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 */
    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 */
{
    void *elementRecord = eclass->elementRecord;
    char *elementRecord = eclass->elementRecord;
    OptionMap optionMap = GetOptionMap(eclass,optionTable);
    int nResources = eclass->nResources;
    Ttk_ResourceCache cache = style->cache;
    const Ttk_ElementOptionSpec *elementOption = eclass->specPtr->options;
    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);
1067
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091
1092







-
+







 *	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. */
    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
1108
1109
1110
1111
1112
1113
1114

1115
1116
1117
1118
1119
1120
1121
1122







-
+







 *	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. */
    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)
1129
1130
1131
1132
1133
1134
1135
1136
1137


1138
1139
1140
1141
1142
1143
1144
1140
1141
1142
1143
1144
1145
1146


1147
1148
1149
1150
1151
1152
1153
1154
1155







-
-
+
+







 * 	Helper routine.  Sets interp's result to the list of all keys
 * 	in the hash table.
 *
 * Returns: TCL_OK.
 * Side effects: Sets interp's result.
 */

MODULE_SCOPE
int TtkEnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht)
MODULE_SCOPE int
TtkEnumerateHashTable(Tcl_Interp *interp, Tcl_HashTable *ht)
{
    Tcl_HashSearch search;
    Tcl_Obj *result = Tcl_NewListObj(0, NULL);
    Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(ht, &search);

    while (entryPtr != NULL) {
	Tcl_Obj *nameObj = Tcl_NewStringObj((const char *)Tcl_GetHashKey(ht, entryPtr),-1);
1174
1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1199







-
+







/* + 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 */
    void *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;
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
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







-
+
















-
+


-
+







    ThemeChanged(pkgPtr);
    return TCL_OK;
}

/* + style configure $style -option ?value...
 */
static int StyleConfigureCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
    void *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:
	Tcl_WrongNumArgs(interp,2,objv,"style ?-option ?value...??");
	return TCL_ERROR;
    }

    styleName = Tcl_GetString(objv[2]);
    stylePtr = Ttk_GetStyle(theme, styleName);

    if (objc == 3) {		/* style default $styleName */
    if (objc == 3) {		/* style configure $styleName */
	Tcl_SetObjResult(interp, HashTableToDict(&stylePtr->defaultsTable));
	return TCL_OK;
    } else if (objc == 4) {	/* style default $styleName -option */
    } else if (objc == 4) {	/* style configure $styleName -option */
	const char *optionName = Tcl_GetString(objv[3]);
	Tcl_HashEntry *entryPtr =
	    Tcl_FindHashEntry(&stylePtr->defaultsTable, optionName);
	if (entryPtr) {
	    Tcl_SetObjResult(interp, (Tcl_Obj*)Tcl_GetHashValue(entryPtr));
	}
	return TCL_OK;
1296
1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309
1310
1307
1308
1309
1310
1311
1312
1313

1314
1315
1316
1317
1318
1319
1320
1321







-
+







    ThemeChanged(pkgPtr);
    return TCL_OK;
}

/* + style lookup $style -option ?statespec? ?defaultValue?
 */
static int StyleLookupCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
    void *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;
1338
1339
1340
1341
1342
1343
1344
1345

1346
1347
1348
1349
1350
1351
1352
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1363







-
+







	Tcl_SetObjResult(interp, result);
    }

    return TCL_OK;
}

static int StyleThemeCurrentCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[])
    void *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) {
1374
1375
1376
1377
1378
1379
1380
1381

1382
1383
1384
1385
1386
1387
1388
1385
1386
1387
1388
1389
1390
1391

1392
1393
1394
1395
1396
1397
1398
1399







-
+







    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[])
    void *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;
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
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







-
+

-
-
+
+













-
+







    }
}

/* + style theme names --
 * 	Return list of registered themes.
 */
static int StyleThemeNamesCmd(
    ClientData clientData,
    void *clientData,
    Tcl_Interp *interp,
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
    TCL_UNUSED(int), /* objc */
    TCL_UNUSED(Tcl_Obj *const *)) /* objv */
{
    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 */
    void *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;
1484
1485
1486
1487
1488
1489
1490
1491

1492
1493
1494
1495
1496
1497
1498
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
1509







-
+








    return status;
}

/* + style element create name type ? ...args ?
 */
static int StyleElementCreateCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
    void *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;

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
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







-
+















-
+














-
-
+
+







	    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[])
    void *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[])
    void *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;
	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;
	}
1573
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587
1584
1585
1586
1587
1588
1589
1590

1591
1592
1593
1594
1595
1596
1597
1598







-
+







    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[])
    void *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) {
1613
1614
1615
1616
1617
1618
1619
1620

1621
1622
1623
1624
1625
1626
1627
1624
1625
1626
1627
1628
1629
1630

1631
1632
1633
1634
1635
1636
1637
1638







-
+







}

/* + style theme use $theme --
 *  	Sets the current theme to $theme
 */
static int
StyleThemeUseCmd(
    ClientData clientData,		/* StylePackageData pointer */
    void *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;

1670
1671
1672
1673
1674
1675
1676
1677

1678
1679
1680
1681
1682
1683
1684
1685
1686


1687
1688
1689
1690
1691
1692
1693
1681
1682
1683
1684
1685
1686
1687

1688
1689
1690
1691
1692
1693
1694
1695


1696
1697
1698
1699
1700
1701
1702
1703
1704







-
+







-
-
+
+







    { "theme", 0, StyleThemeEnsemble },
    { "element", 0, StyleElementEnsemble },
    { NULL, 0, 0 }
};

static int
StyleObjCmd(
    ClientData clientData,		/* StylePackageData pointer */
    void *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 */
MODULE_SCOPE int
Ttk_InvokeEnsemble(	/* Run an ensemble command */
    const Ttk_Ensemble *ensemble, int cmdIndex,
    void *clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    while (cmdIndex < objc) {
	int index;
	if (Tcl_GetIndexFromObjStruct(interp,
		objv[cmdIndex], ensemble, sizeof(ensemble[0]),
Changes to generic/ttk/ttkTheme.h.
71
72
73
74
75
76
77



78
79
80
81
82



83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100
101
102
103








104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121



122
123
124
125
126
127
128
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147







+
+
+





+
+
+









+
+












+
+
+
+
+
+
+
+


















+
+
+








#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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175







+







/*
 * 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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240








241
242
243
244

245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
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 _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);

#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 */
    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 */
    const Ttk_ElementOptionSpec *options;	/* List of options, NULL-terminated */
    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 const Ttk_ElementOptionSpec TtkNullElementOptions[];
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
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319







+
+
+







				{ 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.
 */

338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415



416
417
418
419
420
421
422







-
+












-
+













-
+






-
-
-







 */

typedef struct TtkImageSpec Ttk_ImageSpec;
TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *);
TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *,
					Tk_ImageChangedProc *, ClientData);
TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *);
TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State);
TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Tk_Window, Ttk_State);

/*------------------------------------------------------------------------
 * +++ Miscellaneous enumerations.
 * 	Other stuff that element implementations need to know about.
 */
typedef enum 			/* -default option values */
{
    TTK_BUTTON_DEFAULT_NORMAL,	/* widget defaultable */
    TTK_BUTTON_DEFAULT_ACTIVE,	/* currently the default widget */
    TTK_BUTTON_DEFAULT_DISABLED	/* not defaultable */
} Ttk_ButtonDefaultState;

TTKAPI int Ttk_GetButtonDefaultStateFromObj(Tcl_Interp *, Tcl_Obj *, 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 *, Ttk_Compound *);
TTKAPI int Ttk_GetCompoundFromObj(Tcl_Interp *, Tcl_Obj *, int *);

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: */
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
30
31
32
33
34
35
36
37
38
39
40
41


42
11
12
13
14
15
16
17

18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44







-
+



-
+



















+
+


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,
	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, void *recordPtr, Tk_OptionTable,
	Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable,
	Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state);

MODULE_SCOPE Tcl_Obj *Ttk_QueryStyle(
    Ttk_Style, void *, Tk_OptionTable, const char *, Ttk_State state);

MODULE_SCOPE Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(
	Tcl_Interp *, Tcl_Obj *);
MODULE_SCOPE Tcl_Obj *Ttk_UnparseLayoutTemplate(Ttk_LayoutTemplate);
MODULE_SCOPE Ttk_LayoutTemplate Ttk_BuildLayoutTemplate(Ttk_LayoutSpec);
MODULE_SCOPE void Ttk_FreeLayoutTemplate(Ttk_LayoutTemplate);
MODULE_SCOPE void Ttk_RegisterLayoutTemplate(
    Ttk_Theme theme, const char *layoutName, Ttk_LayoutTemplate);

MODULE_SCOPE Ttk_Style Ttk_GetStyle(Ttk_Theme themePtr, const char *styleName);
MODULE_SCOPE Ttk_LayoutTemplate Ttk_FindLayoutTemplate(
    Ttk_Theme themePtr, const char *layoutName);

MODULE_SCOPE const char *Ttk_StyleName(Ttk_Style);

MODULE_SCOPE int TtkBoxEqual(Ttk_Box, Ttk_Box);

#endif /* _TTKTHEMEINT */
Changes to generic/ttk/ttkTrace.c.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







};

/*
 * Tcl_VarTraceProc for trace handles.
 */
static char *
VarTraceProc(
    ClientData clientData,	/* Widget record pointer */
    void *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;
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124







-
+







/*
 * Ttk_UntraceVariable --
 * 	Remove previously-registered trace and free the handle.
 */
void Ttk_UntraceVariable(Ttk_TraceHandle *h)
{
    if (h) {
	ClientData cd = NULL;
	void *cd = NULL;

	/*
	 * Workaround for Tcl Bug 3062331.  The trace design problem is
	 * that when variable unset traces fire, Tcl documents that the
	 * traced variable has already been unset.  It's already gone.
	 * So from within an unset trace, if you try to call
	 * Tcl_UntraceVar() on that variable, it will do nothing, because
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
12
13
14
15
16
17
18

19
20
21
22

23
24
25
26
27
28
29
30







-
+



-
+







 * 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,
 * 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-Button-2>)
 * TODO: Handle "chords" properly (e.g., <B1-ButtonPress-2>)
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

typedef struct {
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
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;
    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
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));
    ElementStateTracker *es = 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
14
15
16
17

18
19
20
21
22
23
24
1
2
3
4
5
6
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) 2004, Joe English
 *
 * ttk::treeview widget implementation.
 */

#include "tkInt.h"
#include "ttkTheme.h"
#include "ttkWidget.h"

#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXPrivate.h"
#endif

#define DEF_TREE_ROWS		"10"
#define DEF_COLWIDTH		"200"
#define DEF_MINWIDTH		"20"

static const int DEFAULT_ROWHEIGHT 	= 20;
static const int DEFAULT_INDENT 	= 20;
static const int HALO   		= 4;	/* separator */
static const int HALO   		= 4;	/* heading separator */

#define TTK_STATE_OPEN TTK_STATE_USER1
#define TTK_STATE_LEAF TTK_STATE_USER2

#define STATE_CHANGED	 	(0x100)	/* item state option changed */

/*------------------------------------------------------------------------
55
56
57
58
59
60
61
62

63
64

65
66
67

68
69
70

71
72
73

74
75
76

77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
61
62
63
64
65
66
67

68
69

70
71
72

73
74
75

76
77
78

79
80
81

82
83
84

85
86
87



88
89
90
91
92
93
94







-
+

-
+


-
+


-
+


-
+


-
+


-
+


-
-
-







    Ttk_TagSet	tagset;
    Ttk_ImageSpec *imagespec;
};

#define ITEM_OPTION_TAGS_CHANGED	0x100
#define ITEM_OPTION_IMAGE_CHANGED	0x200

static const Tk_OptionSpec ItemOptionSpecs[] = {
static Tk_OptionSpec ItemOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	"", offsetof(TreeItem,textObj), TCL_INDEX_NONE,
	"", Tk_Offset(TreeItem,textObj), -1,
	0,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(TreeItem,imageObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(TreeItem,imageObj), -1,
	TK_OPTION_NULL_OK,0,ITEM_OPTION_IMAGE_CHANGED },
    {TK_OPTION_STRING, "-values", "values", "Values",
	NULL, offsetof(TreeItem,valuesObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(TreeItem,valuesObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_BOOLEAN, "-open", "open", "Open",
	"0", offsetof(TreeItem,openObj), TCL_INDEX_NONE,
	"0", Tk_Offset(TreeItem,openObj), -1,
	0,0,0 },
    {TK_OPTION_STRING, "-tags", "tags", "Tags",
	NULL, offsetof(TreeItem,tagsObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(TreeItem,tagsObj), -1,
	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}
    {TK_OPTION_END, 0,0,0, NULL, -1,-1, 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));

186
187
188
189
190
191
192
193

194
195

196
197
198

199
200
201
202


203
204

205
206
207

208
209
210

211
212
213

214
215
216
217
218
219
220
189
190
191
192
193
194
195

196
197

198
199
200

201
202
203


204
205
206

207
208
209

210
211
212

213
214
215

216
217
218
219
220
221
222
223







-
+

-
+


-
+


-
-
+
+

-
+


-
+


-
+


-
+







    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[] = {
static Tk_OptionSpec TagOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	NULL, offsetof(DisplayItem,textObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(DisplayItem,textObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	NULL, offsetof(DisplayItem,imageObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(DisplayItem,imageObj), -1,
	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>> */
	"center", Tk_Offset(DisplayItem,anchorObj), -1,
	0, 0, GEOMETRY_CHANGED},	/* <<NOTE-ANCHOR>> */
    {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor",
	NULL, offsetof(DisplayItem,backgroundObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(DisplayItem,backgroundObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor",
	NULL, offsetof(DisplayItem,foregroundObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(DisplayItem,foregroundObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_FONT, "-font", "font", "Font",
	NULL, offsetof(DisplayItem,fontObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(DisplayItem,fontObj), -1,
	TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED },

    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
    {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,
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
243
244
245
246
247
248
249


250
251
252
253
254
255
256
257
258







-
-
+
+







    /* Temporary storage for cell data
     */
    Tcl_Obj 	*data;
} TreeColumn;

static void InitColumn(TreeColumn *column)
{
    column->width = 200;
    column->minWidth = 20;
    column->width = atoi(DEF_COLWIDTH);
    column->minWidth = atoi(DEF_MINWIDTH);
    column->stretch = 1;
    column->idObj = 0;
    column->anchorObj = 0;

    column->headingState = 0;
    column->headingObj = 0;
    column->headingImageObj = 0;
270
271
272
273
274
275
276
277

278
279

280
281
282

283
284
285

286
287
288

289
290
291

292
293

294
295
296

297
298

299
300
301

302
303
304

305
306
307

308
309
310

311
312

313
314
315
316
317
318
319
273
274
275
276
277
278
279

280
281

282
283
284

285
286
287

288
289
290

291
292
293

294
295

296
297
298

299
300

301
302
303

304
305
306

307
308
309

310
311
312

313
314

315
316
317
318
319
320
321
322







-
+

-
+


-
+


-
+


-
+


-
+

-
+


-
+

-
+


-
+


-
+


-
+


-
+

-
+







    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[] = {
static Tk_OptionSpec ColumnOptionSpecs[] = {
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_COLWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,width),
	DEF_COLWIDTH, -1, Tk_Offset(TreeColumn,width),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_INT, "-minwidth", "minWidth", "MinWidth",
	DEF_MINWIDTH, TCL_INDEX_NONE, offsetof(TreeColumn,minWidth),
	DEF_MINWIDTH, -1, Tk_Offset(TreeColumn,minWidth),
	0,0,0 },
    {TK_OPTION_BOOLEAN, "-stretch", "stretch", "Stretch",
	"1", TCL_INDEX_NONE, offsetof(TreeColumn,stretch),
	"1", -1, Tk_Offset(TreeColumn,stretch),
	0,0,GEOMETRY_CHANGED },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"w", offsetof(TreeColumn,anchorObj), TCL_INDEX_NONE,	/* <<NOTE-ANCHOR>> */
	"w", Tk_Offset(TreeColumn,anchorObj), -1,	/* <<NOTE-ANCHOR>> */
	0,0,0 },
    {TK_OPTION_STRING, "-id", "id", "ID",
	NULL, offsetof(TreeColumn,idObj), TCL_INDEX_NONE,
	NULL, Tk_Offset(TreeColumn,idObj), -1,
	TK_OPTION_NULL_OK,0,READONLY_OPTION },
    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
    {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
};

static const Tk_OptionSpec HeadingOptionSpecs[] = {
static Tk_OptionSpec HeadingOptionSpecs[] = {
    {TK_OPTION_STRING, "-text", "text", "Text",
	"", offsetof(TreeColumn,headingObj), TCL_INDEX_NONE,
	"", Tk_Offset(TreeColumn,headingObj), -1,
	0,0,0 },
    {TK_OPTION_STRING, "-image", "image", "Image",
	"", offsetof(TreeColumn,headingImageObj), TCL_INDEX_NONE,
	"", Tk_Offset(TreeColumn,headingImageObj), -1,
	0,0,0 },
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	"center", offsetof(TreeColumn,headingAnchorObj), TCL_INDEX_NONE,
	"center", Tk_Offset(TreeColumn,headingAnchorObj), -1,
	0,0,0 },
    {TK_OPTION_STRING, "-command", "", "",
	"", offsetof(TreeColumn,headingCommandObj), TCL_INDEX_NONE,
	"", Tk_Offset(TreeColumn,headingCommandObj), -1,
	TK_OPTION_NULL_OK,0,0 },
    {TK_OPTION_STRING, "state", "", "",
	"", offsetof(TreeColumn,headingStateObj), TCL_INDEX_NONE,
	"", Tk_Offset(TreeColumn,headingStateObj), -1,
	0,0,STATE_CHANGED },
    {TK_OPTION_END, 0,0,0, NULL, TCL_INDEX_NONE,TCL_INDEX_NONE, 0,0,0}
    {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0,0,0}
};

/*------------------------------------------------------------------------
 * +++ -show option:
 * TODO: Implement SHOW_BRANCHES.
 */

377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394







-
+







    Ttk_Layout itemLayout;
    Ttk_Layout cellLayout;
    Ttk_Layout headingLayout;
    Ttk_Layout rowLayout;

    int headingHeight;		/* Space for headings */
    int rowHeight;		/* Height of each item */
    int indent;			/* #pixels horizontal offset for child items */
    int indent;			/* Horizontal offset for child items (screen units) */

    /* Tree data:
     */
    Tcl_HashTable items;	/* Map: item name -> item */
    int serial;			/* Next item # for autogenerated names */
    TreeItem *root;		/* Root item */

434
435
436
437
438
439
440
441

442
443
444


445
446
447


448
449
450


451
452
453
454


455
456
457
458


459
460
461


462
463
464

465
466
467

468
469
470
471
472
473
474
437
438
439
440
441
442
443

444
445


446
447
448


449
450
451


452
453
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 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[] = {
static 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_Offset(Treeview,tree.columnsObj), -1,
	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 },
	"#all", Tk_Offset(Treeview,tree.displayColumnsObj), -1,
	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 },
	DEFAULT_SHOW, Tk_Offset(Treeview,tree.showObj), -1,
	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 },
	"extended", Tk_Offset(Treeview,tree.selectModeObj), -1,
	0, SelectModeStrings, 0 },

    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_TREE_ROWS, offsetof(Treeview,tree.heightObj), TCL_INDEX_NONE,
	0, 0,GEOMETRY_CHANGED},
	DEF_TREE_ROWS, Tk_Offset(Treeview,tree.heightObj), -1,
	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 },
	NULL, Tk_Offset(Treeview,tree.paddingObj), -1,
	TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED },

    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	NULL, TCL_INDEX_NONE, offsetof(Treeview, tree.xscroll.scrollCmd),
	NULL, -1, Tk_Offset(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),
	NULL, -1, Tk_Offset(Treeview, tree.yscroll.scrollCmd),
	TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED},

    WIDGET_TAKEFOCUS_TRUE,
    WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
};

/*------------------------------------------------------------------------
693
694
695
696
697
698
699
700

701
702
703

704
705
706
707
708
709
710
696
697
698
699
700
701
702

703
704
705

706
707
708
709
710
711
712
713







-
+


-
+








	Tcl_HashEntry *entryPtr = Tcl_CreateHashEntry(
	    &tv->tree.columnNames, Tcl_GetString(columnName), &isNew);
	Tcl_SetHashValue(entryPtr, tv->tree.columns + i);

	InitColumn(tv->tree.columns + i);
	Tk_InitOptions(
	    interp, (ClientData)(tv->tree.columns + i),
	    interp, (void *)(tv->tree.columns + i),
	    tv->tree.columnOptionTable, tv->core.tkwin);
	Tk_InitOptions(
	    interp, (ClientData)(tv->tree.columns + i),
	    interp, (void *)(tv->tree.columns + i),
	    tv->tree.headingOptionTable, tv->core.tkwin);
	Tcl_IncrRefCount(columnName);
	tv->tree.columns[i].idObj = columnName;
    }

    return TCL_OK;
}
863
864
865
866
867
868
869

870

871
872
873
874
875
876
877
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
881







+
-
+







 * 	The "((++w % m) < r)" term is there so that the remainder r = n % m
 * 	is distributed round-robin.
 */
static int DistributeWidth(Treeview *tv, int n)
{
    int w = TreeWidth(tv);
    int m = 0;
    int i;
    int i, d, r;
    int d, r;

    for (i = FirstColumn(tv); i < tv->tree.nDisplayColumns; ++i) {
	if (tv->tree.displayColumns[i]->stretch) {
	    ++m;
	}
    }
    if (m == 0) {
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
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







-
+


-
+










-
+







    tv->tree.nColumns = tv->tree.nDisplayColumns = 0;
    tv->tree.columns = NULL;
    tv->tree.displayColumns = NULL;
    tv->tree.showFlags = ~0;

    InitColumn(&tv->tree.column0);
    Tk_InitOptions(
	interp, (ClientData)(&tv->tree.column0),
	interp, (void *)(&tv->tree.column0),
	tv->tree.columnOptionTable, tv->core.tkwin);
    Tk_InitOptions(
	interp, (ClientData)(&tv->tree.column0),
	interp, (void *)(&tv->tree.column0),
	tv->tree.headingOptionTable, tv->core.tkwin);

    Tcl_InitHashTable(&tv->tree.items, TCL_STRING_KEYS);
    tv->tree.serial = 0;

    tv->tree.focus = tv->tree.endPtr = 0;

    /* Create root item "":
     */
    tv->tree.root = NewItem();
    Tk_InitOptions(interp, (ClientData)tv->tree.root,
    Tk_InitOptions(interp, (void *)tv->tree.root,
	tv->tree.itemOptionTable, tv->core.tkwin);
    tv->tree.root->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
    tv->tree.root->entryPtr = Tcl_CreateHashEntry(&tv->tree.items, "", &unused);
    Tcl_SetHashValue(tv->tree.root->entryPtr, tv->tree.root);

    /* Scroll handles:
     */
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
1066
1067
1068
1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079
1080







-
+







    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);
	ckfree((void *)tv->tree.displayColumns);

    foreachHashEntry(&tv->tree.items, FreeItemCB);
    Tcl_DeleteHashTable(&tv->tree.items);

    TtkFreeScrollHandle(tv->tree.xscrollHandle);
    TtkFreeScrollHandle(tv->tree.yscrollHandle);
}
1126
1127
1128
1129
1130
1131
1132
1133

1134
1135
1136
1137
1138
1139
1140
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
1144







-
+







    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,
    if (Tk_SetOptions(interp, (void *)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
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







-
+




















-
+


-
+







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,
    if (Tk_SetOptions(interp, (void *)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 {
	} else {
	    RecomputeSlack(tv);
	    ResizeColumns(tv, TreeWidth(tv));
        }
	}
    }
    TtkRedisplayWidget(&tv->core);

    Tk_FreeSavedOptions(&savedOptions);
    return TCL_OK;

error:
1252
1253
1254
1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
1256
1257
1258
1259
1260
1261
1262

1263
1264
1265
1266
1267
1268
1269
1270







-
+







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,
    if (Tk_SetOptions(interp, (void *)column,
	    tv->tree.headingOptionTable, objc, objv, tv->core.tkwin,
	    &savedOptions,&mask) != TCL_OK)
    {
	return TCL_ERROR;
    }

    /* @@@ testing ... */
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
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







+
+
+
+













-
+
+







    Treeview *tv,		/* treeview widget */
    TreeItem *item,		/* desired item */
    TreeColumn *column,		/* desired column */
    Ttk_Box *bbox_rtn)		/* bounding box of item */
{
    int row = ItemRow(tv, item);
    Ttk_Box bbox = tv->tree.treeArea;

    /* Make sure the scroll information is current before use */
    TtkUpdateScrollInfo(tv->tree.xscrollHandle);
    TtkUpdateScrollInfo(tv->tree.yscrollHandle);

    if (row < tv->tree.yscroll.first || row > tv->tree.yscroll.last) {
	/* not viewable, or off-screen */
	return 0;
    }

    bbox.y += (row - tv->tree.yscroll.first) * tv->tree.rowHeight;
    bbox.height = tv->tree.rowHeight;

    bbox.x -= tv->tree.xscroll.first;
    bbox.width = TreeWidth(tv);

    if (column) {
	int xpos = 0, i = FirstColumn(tv);
	int xpos = 0;
	int i = FirstColumn(tv);
	while (i < tv->tree.nDisplayColumns) {
	    if (tv->tree.displayColumns[i] == column) {
		break;
	    }
	    xpos += tv->tree.displayColumns[i]->width;
	    ++i;
	}
1504
1505
1506
1507
1508
1509
1510
1511


1512
1513
1514
1515
1516
1517
1518
1519
1520
1513
1514
1515
1516
1517
1518
1519

1520
1521
1522

1523
1524
1525
1526
1527
1528
1529







-
+
+

-








static const char *const regionStrings[] = {
    "nothing", "heading", "separator", "tree", "cell", 0
};

static TreeRegion IdentifyRegion(Treeview *tv, int x, int y)
{
    int x1 = 0, colno;
    int x1 = 0;
    int colno = IdentifyDisplayColumn(tv, x, &x1);

    colno = IdentifyDisplayColumn(tv, x, &x1);
    if (Ttk_BoxContains(tv->tree.headingArea, x, y)) {
	if (colno < 0) {
	    return REGION_NOTHING;
	} else if (-HALO <= x1 - x  && x1 - x <= HALO) {
	    return REGION_SEPARATOR;
	} else {
	    return REGION_HEADING;
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594


1595
1596



1597
1598

1599
1600
1601
1602
1603
1604
1605
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







-




+
+
-
-
+
+
+

-
+








    /* Compute heading height.
     */
    Ttk_RebindSublayout(tv->tree.headingLayout, &tv->tree.column0);
    Ttk_LayoutSize(tv->tree.headingLayout, 0, &unused, &tv->tree.headingHeight);

    /* Get item height, indent from style:
     * @@@ TODO: sanity-check.
     */
    tv->tree.rowHeight = DEFAULT_ROWHEIGHT;
    tv->tree.indent = DEFAULT_INDENT;
    if ((objPtr = Ttk_QueryOption(treeLayout, "-rowheight", 0))) {
	(void)Tk_GetPixelsFromObj(NULL, tv->core.tkwin, objPtr, &tv->tree.rowHeight);
	if (tv->tree.rowHeight < 1) {
	(void)Tcl_GetIntFromObj(NULL, objPtr, &tv->tree.rowHeight);
    }
	    tv->tree.rowHeight = 1;
	}
    }
    if ((objPtr = Ttk_QueryOption(treeLayout, "-indent", 0))) {
	(void)Tcl_GetIntFromObj(NULL, objPtr, &tv->tree.indent);
	(void)Tk_GetPixelsFromObj(NULL, tv->core.tkwin, objPtr, &tv->tree.indent);
    }

    return treeLayout;
}

/* + TreeviewDoLayout --
 * 	DoLayout() widget hook.  Computes widget layout.
1627
1628
1629
1630
1631
1632
1633
1634
1635

1636
1637
1638
1639
1640
1641
1642
1638
1639
1640
1641
1642
1643
1644

1645
1646
1647
1648
1649
1650
1651
1652
1653







-

+







    if (tv->tree.showFlags & SHOW_HEADINGS) {
	tv->tree.headingArea = Ttk_PackBox(
	    &tv->tree.treeArea, 1, tv->tree.headingHeight, TTK_SIDE_TOP);
    } else {
	tv->tree.headingArea = Ttk_MakeBox(0,0,0,0);
    }

    visibleRows = tv->tree.treeArea.height / tv->tree.rowHeight;
    tv->tree.root->state |= TTK_STATE_OPEN;
    visibleRows = tv->tree.treeArea.height / tv->tree.rowHeight;
    TtkScrolled(tv->tree.yscrollHandle,
	    tv->tree.yscroll.first,
	    tv->tree.yscroll.first + visibleRows,
	    CountRows(tv->tree.root) - 1);
}

/* + TreeviewSize --
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
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







+
+
-
-
-
+
+
+
+
+
+
+
+








-
+
+












-
+







 * 	Draw an item (row background, tree label, and cells).
 */
static void DrawItem(
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{
    Ttk_State state = ItemState(tv, item);
    DisplayItem displayItem;
    int x, y, h, rowHeight;

    int rowHeight = tv->tree.rowHeight;
    int x = tv->tree.treeArea.x - tv->tree.xscroll.first;
    int y = tv->tree.treeArea.y + rowHeight * (row - tv->tree.yscroll.first);
    rowHeight = tv->tree.rowHeight;
    h = rowHeight * (row - tv->tree.yscroll.first);
    if (h >= tv->tree.treeArea.height) {
	/* The item is outside the visible area */
	return;
    }
    x = tv->tree.treeArea.x - tv->tree.xscroll.first;
    y = tv->tree.treeArea.y + h;

    if (row % 2) state |= TTK_STATE_ALTERNATE;

    PrepareItem(tv, item, &displayItem);

    /* Draw row background:
     */
    {
	Ttk_Box rowBox = Ttk_MakeBox(x, y, TreeWidth(tv), rowHeight);
	Ttk_Box rowBox = Ttk_MakeBox(tv->tree.treeArea.x, y,
				     TreeWidth(tv), rowHeight);
	DisplayLayout(tv->tree.rowLayout, &displayItem, state, rowBox, d);
    }

    /* Draw tree label:
     */
    if (tv->tree.showFlags & SHOW_TREE) {
	int indent = depth * tv->tree.indent;
	int colwidth = tv->tree.column0.width;
	Ttk_Box parcel = Ttk_MakeBox(
		x+indent, y, colwidth-indent, rowHeight);
	if (item->textObj) { displayItem.textObj = item->textObj; }
	if (item->imageObj) { displayItem.imageObj = item->imageObj; }
        displayItem.anchorObj = tv->tree.column0.anchorObj;
	displayItem.anchorObj = tv->tree.column0.anchorObj;
	DisplayLayout(tv->tree.itemLayout, &displayItem, state, parcel, d);
	x += colwidth;
    }

    /* Draw data cells:
     */
    DrawCells(tv, item, &displayItem, d, x, y);
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
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







-
-
+
+




+
+
+
+
+
+
+
+
+
+







+
+

+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 *
 * Returns:
 * 	Row number of the last item drawn.
 */
static int DrawForest(
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{
    while (item && row < tv->tree.yscroll.last) {
        row = DrawSubtree(tv, item, d, depth, row);
    while (item && row <= tv->tree.yscroll.last) {
	row = DrawSubtree(tv, item, d, depth, row);
	item = item->next;
    }
    return row;
}

/* + DrawTreeArea --
 * 	Draw the tree area including the headings, if any
 */
static void DrawTreeArea(Treeview *tv, Drawable d) {
    if (tv->tree.showFlags & SHOW_HEADINGS) {
	DrawHeadings(tv, d);
    }
    DrawForest(tv, tv->tree.root->children, d, 0, 0);
}

/* + TreeviewDisplay --
 * 	Display() widget hook.  Draw the widget contents.
 */
static void TreeviewDisplay(void *clientData, Drawable d)
{
    Treeview *tv = (Treeview *)clientData;
    Tk_Window tkwin = tv->core.tkwin;
    int width, height, winWidth, winHeight;

    /* Draw the general layout of the treeview widget */
    Ttk_DrawLayout(tv->core.layout, tv->core.state, d);

    /* When the tree area does not fit in the available space, there is a
     * risk that it will be drawn over other areas of the layout.
     */

    winWidth = Tk_Width(tkwin);
    winHeight = Tk_Height(tkwin);
    width = tv->tree.treeArea.width;
    height = tv->tree.headingArea.height + tv->tree.treeArea.height;

    if ((width == winWidth && height == winHeight)
      || (tv->tree.treeArea.height % tv->tree.rowHeight == 0
	&& TreeWidth(tv) <= width)) {
	/* No protection is needed; either the tree area fills the entire
	 * widget, or everything fits within the available area.
	 */
	DrawTreeArea(tv, d);
    } else {
	/* The tree area needs to be clipped
	 */

	int x, y;
#ifndef TK_NO_DOUBLE_BUFFERING
	Drawable p;
	XGCValues gcValues;
	GC gc;
#endif /* TK_NO_DOUBLE_BUFFERING */

	x = tv->tree.treeArea.x;
    if (tv->tree.showFlags & SHOW_HEADINGS) {
	DrawHeadings(tv, d);
    }
    DrawForest(tv, tv->tree.root->children, d, 0,0);
	if (tv->tree.showFlags & SHOW_HEADINGS) {
	    y = tv->tree.headingArea.y;
	} else {
	    y = tv->tree.treeArea.y;
	}

#ifndef TK_NO_DOUBLE_BUFFERING
	/* Create a temporary helper drawable */
	p = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
	  winWidth, winHeight, Tk_Depth(tkwin));

	/* Get a graphics context for copying the drawable content */
	gcValues.function = GXcopy;
	gcValues.graphics_exposures = False;
	gc = Tk_GetGC(tkwin, GCFunction|GCGraphicsExposures, &gcValues);

	/* Copy the widget background into the helper */
	XCopyArea(Tk_Display(tkwin), d, p, gc, 0, 0,
	  (unsigned) winWidth, (unsigned) winHeight, 0, 0);

	/* Draw the tree onto the helper without regard for borders */
	DrawTreeArea(tv, p);

	/* Copy only the tree area inside the borders back */
	XCopyArea(Tk_Display(tkwin), p, d, gc, x, y,
	  (unsigned) width, (unsigned) height, x, y);

	/* Clean up the temporary resources */
	Tk_FreePixmap(Tk_Display(tkwin), p);
	Tk_FreeGC(Tk_Display(tkwin), gc);
#else
	Ttk_Theme currentTheme = Ttk_GetCurrentTheme(tv->core.interp);
	Ttk_Theme aquaTheme = Ttk_GetTheme(tv->core.interp, "aqua");
	if (currentTheme == aquaTheme && [NSApp macOSVersion] > 100800) {
	    y -= 4;
	    height += 4;
	}

	TkpClipDrawableToRect(Tk_Display(tkwin), d, x, y, width, height);
	DrawTreeArea(tv, d);
	TkpClipDrawableToRect(Tk_Display(tkwin), d, 0, 0, -1, -1);
#endif
    }
}

/*------------------------------------------------------------------------
 * +++ Utilities for widget commands
 */

/* + InsertPosition --
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
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







-
+

















-
+








-
+







	int i;

	if (!newChildren)
	    return TCL_ERROR;

	/* Sanity-check:
	 */
	for (i=0; newChildren[i]; ++i) {
	for (i = 0; newChildren[i]; ++i) {
	    if (!AncestryCheck(interp, tv, newChildren[i], item)) {
		ckfree(newChildren);
		return TCL_ERROR;
	    }
	}

	/* Detach old children:
	 */
	child = item->children;
	while (child) {
	    TreeItem *next = child->next;
	    DetachItem(child);
	    child = next;
	}

	/* Detach new children from their current locations:
	 */
	for (i=0; newChildren[i]; ++i) {
	for (i = 0; newChildren[i]; ++i) {
	    DetachItem(newChildren[i]);
	}

	/* Reinsert new children:
	 * Note: it is not an error for an item to be listed more than once,
	 * though it probably should be...
	 */
	child = 0;
	for (i=0; newChildren[i]; ++i) {
	for (i = 0; newChildren[i]; ++i) {
	    if (newChildren[i]->parent) {
		/* This is a duplicate element which has already been
		 * inserted.  Ignore it.
		 */
		continue;
	    }
	    InsertItem(item, child, newChildren[i]);
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
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







-
+















-
+


















-
+







 * 	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;
    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, TkNewIndexObj(index));
    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 = (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));
    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(
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
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







-
+




















-
+
+
+
+





-
+

-



-
-
+
+







-
+







	return TCL_ERROR;
    }

    item = FindItem(interp, tv, objv[2]);
    if (!item) {
	return TCL_ERROR;
    }
    if (objc >=4 && (column = FindColumn(interp,tv,objv[3])) == NULL) {
    if (objc >= 4 && (column = FindColumn(interp,tv,objv[3])) == NULL) {
	return TCL_ERROR;
    }

    if (BoundingBox(tv, item, column, &bbox)) {
	Tcl_SetObjResult(interp, Ttk_NewBoxObj(bbox));
    }

    return TCL_OK;
}

/* + $tv identify $x $y -- (obsolescent)
 * 	Implements the old, horrible, 2-argument form of [$tv identify].
 *
 * Returns: one of
 * 	heading #n
 * 	cell itemid #n
 * 	item itemid element
 * 	row itemid
 */
static int TreeviewHorribleIdentify(
    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Treeview *tv)
    Tcl_Interp *interp,
    TCL_UNUSED(int), /* objc */
    Tcl_Obj *const objv[],
    Treeview *tv)
{
    const char *what = "nothing", *detail = NULL;
    TreeItem *item = 0;
    Tcl_Obj *result;
    int dColumnNumber;
    char dcolbuf[16];
    char dcolbuf[32];
    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) {
    if (Tk_GetPixelsFromObj(interp, tv->core.tkwin, objv[2], &x) != TCL_OK
	    || Tk_GetPixelsFromObj(interp, tv->core.tkwin, objv[3], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    dColumnNumber = IdentifyDisplayColumn(tv, x, &x1);
    if (dColumnNumber < 0) {
	goto done;
    }
    sprintf(dcolbuf, "#%d", dColumnNumber);
    snprintf(dcolbuf, sizeof(dcolbuf), "#%d", dColumnNumber);

    if (Ttk_BoxContains(tv->tree.headingArea,x,y)) {
	if (-HALO <= x1 - x  && x1 - x <= HALO) {
	    what = "separator";
	} else {
	    what = "heading";
	}
2226
2227
2228
2229
2230
2231
2232
2233
2234


2235
2236
2237
2238
2239
2240
2241
2328
2329
2330
2331
2332
2333
2334


2335
2336
2337
2338
2339
2340
2341
2342
2343







-
-
+
+







	    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; }
	    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);
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
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







-
+
+










-
-
+
+



+
+
+
+







    int submethod;
    int x, y;

    TreeRegion region;
    Ttk_Box bbox;
    TreeItem *item;
    TreeColumn *column = 0;
    int colno, x1;
    int colno;
    int 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
	|| Tk_GetPixelsFromObj(interp, tv->core.tkwin, objv[3], &x) != TCL_OK
	|| Tk_GetPixelsFromObj(interp, tv->core.tkwin, objv[4], &y) != TCL_OK
    ) {
	return TCL_ERROR;
    }

    /* Make sure the scroll information is current before use */
    TtkUpdateScrollInfo(tv->tree.xscrollHandle);
    TtkUpdateScrollInfo(tv->tree.yscrollHandle);

    region = IdentifyRegion(tv, x, y);
    item = IdentifyItem(tv, y);
    colno = IdentifyDisplayColumn(tv, x, &x1);
    column = (colno >= 0) ?  tv->tree.displayColumns[colno] : NULL;

    switch (submethod)
2340
2341
2342
2343
2344
2345
2346
2347
2348


2349
2350
2351
2352
2353
2354
2355
2447
2448
2449
2450
2451
2452
2453


2454
2455
2456
2457
2458
2459
2460
2461
2462







-
-
+
+







	    }

	    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; }
	    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));
2370
2371
2372
2373
2374
2375
2376
2377

2378
2379
2380
2381
2382
2383
2384
2477
2478
2479
2480
2481
2482
2483

2484
2485
2486
2487
2488
2489
2490
2491







-
+







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??...");
	Tcl_WrongNumArgs(interp, 2, objv, "item ?option ?value??...");
	return TCL_ERROR;
    }
    if (!(item = FindItem(interp, tv, objv[2]))) {
	return TCL_ERROR;
    }

    if (objc == 3) {
2476
2477
2478
2479
2480
2481
2482
2483

2484
2485
2486
2487
2488
2489
2490
2583
2584
2585
2586
2587
2588
2589

2590
2591
2592
2593
2594
2595
2596
2597







-
+







    }

    if (objc == 3) {
	/* Return dictionary:
	 */
	Tcl_Obj *result = Tcl_NewListObj(0,0);
	Tcl_Obj *value;
	for (columnNumber=0; columnNumber<tv->tree.nColumns; ++columnNumber) {
	for (columnNumber = 0; columnNumber < tv->tree.nColumns; ++columnNumber) {
	    Tcl_ListObjIndex(interp, item->valuesObj, columnNumber, &value);
	    if (value) {
		Tcl_ListObjAppendElement(NULL, result,
			tv->tree.columns[columnNumber].idObj);
		Tcl_ListObjAppendElement(NULL, result, value);
	    }
	}
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
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







-
+








-
+


-
+















-
-
+
+







	    return TCL_ERROR;
	}
	objc -= 2; objv += 2;
    } else {
	char idbuf[16];
	do {
	    ++tv->tree.serial;
	    sprintf(idbuf, "I%03X", tv->tree.serial);
	    snprintf(idbuf, sizeof(idbuf), "I%03X", tv->tree.serial);
	    entryPtr = Tcl_CreateHashEntry(&tv->tree.items, idbuf, &isNew);
	} while (!isNew);
    }

    /* Create and configure new item:
     */
    newItem = NewItem();
    Tk_InitOptions(
	interp, (ClientData)newItem, tv->tree.itemOptionTable, tv->core.tkwin);
	interp, (void *)newItem, tv->tree.itemOptionTable, tv->core.tkwin);
    newItem->tagset = Ttk_GetTagSetFromObj(NULL, tv->tree.tagTable, NULL);
    if (ConfigureItem(interp, tv, newItem, objc, objv) != TCL_OK) {
    	Tcl_DeleteHashEntry(entryPtr);
	Tcl_DeleteHashEntry(entryPtr);
	FreeItem(newItem);
	return TCL_ERROR;
    }

    /* Store in hash table, link into tree:
     */
    Tcl_SetHashValue(entryPtr, newItem);
    newItem->entryPtr = entryPtr;
    InsertItem(parent, sibling, newItem);
    TtkRedisplayWidget(&tv->core);

    Tcl_SetObjResult(interp, ItemID(tv, newItem));
    return TCL_OK;
}

/* + $tv detach $item --
 * 	Unlink $item from the tree.
/* + $tv detach $items --
 * 	Unlink each item in $items 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;
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
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







-
+
+












-
+












-
-
-
-
+
+
+
+
















-
-
+
+







 */

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;
    int i;
    int selChange = 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) {
    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;
        }
    for (i = 0; items[i]; ++i) {
	if (items[i]->state & TTK_STATE_SELECTED) {
	    selChange = 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);
    if (selChange) {
	TtkSendVirtualEvent(tv->core.tkwin, "TreeviewSelect");
    }
    TtkRedisplayWidget(&tv->core);
    return TCL_OK;
}

/* + $tv move $item $parent $index
 * 	Move $item to the specified $index in $parent's child list.
2837
2838
2839
2840
2841
2842
2843



2844
2845
2846
2847
2848
2849





2850
2851







2852
2853
2854
2855
2856
2857
2858
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







+
+
+



-
-
-
+
+
+
+
+


+
+
+
+
+
+
+







	    parent->openObj = unshareObj(parent->openObj);
	    Tcl_SetBooleanObj(parent->openObj, 1);
	    parent->state |= TTK_STATE_OPEN;
	    TtkRedisplayWidget(&tv->core);
	}
    }

    /* Update the scroll information, if necessary */
    TtkUpdateScrollInfo(tv->tree.yscrollHandle);

    /* 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) {
    if (rowNumber < 0) {
	/* The item cannot be moved into view because it is detached */
	return TCL_OK;
    }
    if (rowNumber >= tv->tree.yscroll.last) {
	TtkScrollTo(tv->tree.yscrollHandle,
	    tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last), 1);
    }
    /* On small widgets (shorter than one row high, which is also the case
     * before the widget is initially mapped) the above command will have
     * scrolled down too far. This is why both conditions must be checked.
     */
    if (rowNumber < tv->tree.yscroll.first) {
	TtkScrollTo(tv->tree.yscrollHandle, rowNumber, 1);
    }

    return TCL_OK;
}

/*------------------------------------------------------------------------
 * +++ Widget commands -- interactive column resize
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
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







-
+













-
+
















+

+
-
-
+
+
+
-
+
+
+
+
+
+


+
-
+
+
+




+
-
+
+
+





+





+
-
+
+




















-
+







	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;
    int selop, i, selChange = 0;
    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?");
	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:
	    /* Clear */
	    for (item=tv->tree.root; item; item = NextPreorder(item)) {
		if (item->state & TTK_STATE_SELECTED) {
		item->state &= ~TTK_STATE_SELECTED;
	    }
		    item->state &= ~TTK_STATE_SELECTED;
		    selChange = 1;
		}
	    /*FALLTHRU*/
	    }
	    for (i=0; items[i]; ++i) {
		items[i]->state |= TTK_STATE_SELECTED;
		selChange = 1;
	    }
	    break;
	case SELECTION_ADD:
	    for (i=0; items[i]; ++i) {
		if (!(items[i]->state & TTK_STATE_SELECTED)) {
		items[i]->state |= TTK_STATE_SELECTED;
		    items[i]->state |= TTK_STATE_SELECTED;
		    selChange = 1;
		}
	    }
	    break;
	case SELECTION_REMOVE:
	    for (i=0; items[i]; ++i) {
		if (items[i]->state & TTK_STATE_SELECTED) {
		items[i]->state &= ~TTK_STATE_SELECTED;
		    items[i]->state &= ~TTK_STATE_SELECTED;
		    selChange = 1;
		}
	    }
	    break;
	case SELECTION_TOGGLE:
	    for (i=0; items[i]; ++i) {
		items[i]->state ^= TTK_STATE_SELECTED;
		selChange = 1;
	    }
	    break;
    }

    ckfree(items);
    if (selChange) {
    Tk_SendVirtualEvent(tv->core.tkwin, "TreeviewSelect", NULL);
	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 = (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?");
	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?script?");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tagTable, objv[3]);
    if (!tag) { return TCL_ERROR; }

    if (objc == 4) {		/* $tv tag bind $tag */
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
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







-
+




















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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 ...??");
	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?-option ?value ...??");
	return TCL_ERROR;
    }

    tag = Ttk_GetTagFromObj(tagTable, objv[3]);

    if (objc == 4) {
	return Ttk_EnumerateTagOptions(interp, tagTable, tag);
    } else if (objc == 5) {
	Tcl_Obj *result = Ttk_TagOptionValue(interp, tagTable, tag, objv[4]);
	if (result) {
	    Tcl_SetObjResult(interp, result);
	    return TCL_OK;
	} /* else */
	return TCL_ERROR;
    }
    /* else */
    TtkRedisplayWidget(&tv->core);
    return Ttk_ConfigureTag(interp, tagTable, tag, objc - 4, objv + 4);
}

/* + $tv tag 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;

3152
3153
3154
3155
3156
3157
3158
3159

3160
3161
3162

3163
3164
3165
3166
3167

3168
3169
3170
3171
3172
3173
3174
3261
3262
3263
3264
3265
3266
3267

3268
3269
3270

3271
3272
3273
3274
3275

3276
3277
3278
3279
3280
3281
3282
3283







-
+


-
+




-
+







    } 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)));
	    Tcl_NewBooleanObj(Ttk_TagSetContains(item->tagset, tag)));
	return TCL_OK;
    } else {
    	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?item?");
	Tcl_WrongNumArgs(interp, 3, objv, "tagName ?item?");
	return TCL_ERROR;
    }
}

/* + $tv tag names $tag
/* + $tv tag names
 */
static int TreeviewTagNamesCommand(
    void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    Treeview *tv = (Treeview *)recordPtr;

    if (objc != 3) {
3206
3207
3208
3209
3210
3211
3212
3213

3214
3215
3216
3217
3218
3219
3220
3315
3316
3317
3318
3319
3320
3321

3322
3323
3324
3325
3326
3327
3328
3329







-
+







    tag = Ttk_GetTagFromObj(tv->tree.tagTable, objv[3]);
    items = GetItemListFromObj(interp, tv, objv[4]);

    if (!items) {
	return TCL_ERROR;
    }

    for (i=0; items[i]; ++i) {
    for (i = 0; items[i]; ++i) {
	AddTag(items[i], tag);
    }

    TtkRedisplayWidget(&tv->core);

    return TCL_OK;
}
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
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







-
+



















-







    if (objc == 5) {
	TreeItem **items = GetItemListFromObj(interp, tv, objv[4]);
	int i;

	if (!items) {
	    return TCL_ERROR;
	}
	for (i=0; items[i]; ++i) {
	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 }
};

/*------------------------------------------------------------------------
3312
3313
3314
3315
3316
3317
3318
3319

3320
3321
3322
3323
3324
3325
3326
3420
3421
3422
3423
3424
3425
3426

3427
3428
3429
3430
3431
3432
3433
3434







-
+







    { 0,0,0 }
};

/*------------------------------------------------------------------------
 * +++ Widget definition.
 */

static const WidgetSpec TreeviewWidgetSpec = {
static WidgetSpec TreeviewWidgetSpec = {
    "Treeview",			/* className */
    sizeof(Treeview),   	/* recordSize */
    TreeviewOptionSpecs,	/* optionSpecs */
    TreeviewCommands,   	/* subcommands */
    TreeviewInitialize,   	/* initializeProc */
    TreeviewCleanup,		/* cleanupProc */
    TreeviewConfigure,    	/* configureProc */
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
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







-
+

-
+

-
+

-
+




+
-
-
+
+
+
+
+


-

-
-
+

-

+
+






+
-
-
+
+
+
+
+





+


-




-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










-
+
















-
+

-
+

-
+




+
-
-
+
+
+
+
+




-
-





-
+











-
-
+
+








typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *sizeObj;
    Tcl_Obj *marginsObj;
} TreeitemIndicator;

static const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
static Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {
    { "-foreground", TK_OPTION_COLOR,
	offsetof(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
	Tk_Offset(TreeitemIndicator,colorObj), DEFAULT_FOREGROUND },
    { "-indicatorsize", TK_OPTION_PIXELS,
	offsetof(TreeitemIndicator,sizeObj), "12" },
	Tk_Offset(TreeitemIndicator,sizeObj), "12" },
    { "-indicatormargins", TK_OPTION_STRING,
	offsetof(TreeitemIndicator,marginsObj), "2 2 4 2" },
	Tk_Offset(TreeitemIndicator,marginsObj), "2 2 4 2" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void TreeitemIndicatorSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    TreeitemIndicator *indicator = (TreeitemIndicator *)elementRecord;
    Ttk_Padding margins;
    int size = 0;
    (void)dummy;
    (void)paddingPtr;
    Ttk_Padding margins;

    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginsObj, &margins);
    Tk_GetPixelsFromObj(NULL, tkwin, indicator->sizeObj, &size);
    if (size % 2 == 0) --size;	/* An odd size is better for the indicator. */
    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginsObj, &margins);

    *widthPtr = size + Ttk_PaddingWidth(margins);
    *heightPtr = size + Ttk_PaddingHeight(margins);
}

static void TreeitemIndicatorDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
    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;
    int cx, cy;
    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);
    Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginsObj, &margins);
    b = Ttk_PadBox(b, margins);

    switch (direction) {
	case ARROW_DOWN:
	    TtkArrowSize(b.width/2, direction, &cx, &cy);
	    if ((b.height - cy) % 2 == 1) {
		++cy;
	    }
	    break;
	case ARROW_RIGHT:
	default:
	    TtkArrowSize(b.height/2, direction, &cx, &cy);
	    if ((b.width - cx) % 2 == 1) {
		++cx;
	    }
	    break;
    }

    b = Ttk_AnchorBox(b, cx, cy, TK_ANCHOR_CENTER);

    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 = {
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 const Ttk_ElementOptionSpec RowElementOptions[] = {
static Ttk_ElementOptionSpec RowElementOptions[] = {
    { "-background", TK_OPTION_COLOR,
	offsetof(RowElement,backgroundObj), DEFAULT_BACKGROUND },
	Tk_Offset(RowElement,backgroundObj), DEFAULT_BACKGROUND },
    { "-rownumber", TK_OPTION_INT,
	offsetof(RowElement,rowNumberObj), "0" },
	Tk_Offset(RowElement,rowNumberObj), "0" },
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void RowElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
static Ttk_ElementSpec RowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(RowElement),
    RowElementOptions,
    TtkNullElementSize,
    RowElementDraw
};

/*------------------------------------------------------------------------
 * +++ Initialisation.
 */

MODULE_SCOPE
void TtkTreeview_Init(Tcl_Interp *interp)
MODULE_SCOPE void
TtkTreeview_Init(Tcl_Interp *interp)
{
    Ttk_Theme theme = Ttk_GetDefaultTheme(interp);

    RegisterWidget(interp, "ttk::treeview", &TreeviewWidgetSpec);

    Ttk_RegisterElement(interp, theme, "Treeitem.indicator",
	    &TreeitemIndicatorElementSpec, 0);
Changes to generic/ttk/ttkWidget.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17










-
-
-
-







/*
 * 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

/*------------------------------------------------------------------------
 * +++ Internal helper routines.
 */

/* UpdateLayout --
 * 	Call the widget's get-layout hook to recompute corePtr->layout.
 * 	Returns TCL_OK if successful, returns TCL_ERROR and leaves
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99







-
+







-
+








    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;}
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 = (WidgetCore *)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);
114
115
116
117
118
119
120













121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140

141
142
143
144
145
146
147







+
+
+
+
+
+
+
+
+
+
+
+
+










-
+
-







    }

    if (!(corePtr->flags & REDISPLAY_PENDING)) {
	Tcl_DoWhenIdle(DrawWidget, corePtr);
	corePtr->flags |= REDISPLAY_PENDING;
    }
}

/*
 * 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);
}

/* TtkResizeWidget --
 * 	Recompute widget size, schedule geometry propagation and redisplay.
 */
void TtkResizeWidget(WidgetCore *corePtr)
{
    if (corePtr->flags & WIDGET_DESTROYED) {
	return;
    }

    SizeChanged(corePtr);
    WidgetWorldChanged(corePtr);
    TtkRedisplayWidget(corePtr);
}

/* TtkWidgetChangeState --
 * 	Set / clear the specified bits in the 'state' flag,
 */
void TtkWidgetChangeState(WidgetCore *corePtr,
    unsigned int setBits, unsigned int clearBits)
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+







/* WidgetInstanceObjCmd --
 *	Widget instance command implementation.
 */
static int
WidgetInstanceObjCmd(
    ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
    WidgetCore *corePtr = (WidgetCore *)clientData;
    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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
191
192
193
194
195
196
197

198
199
200
201
202
203









204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244


245
246
247
248
249
250
251







-
+





-
-
-
-
-
-
-
-
-











-
+
















-
+












-
-








/* WidgetInstanceObjCmdDeleted --
 * 	Widget instance command	deletion callback.
 */
static void
WidgetInstanceObjCmdDeleted(ClientData clientData)
{
    WidgetCore *corePtr = (WidgetCore *)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(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);
	(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, (Tcl_FreeProc *) FreeWidget);
    Tcl_EventuallyFree(corePtr, TCL_DYNAMIC);
}

/*
 * CoreEventProc --
 *	Event handler for basic events.
 *	Processes Expose, Configure, FocusIn/Out, and Destroy events.
 *	Also handles <<ThemeChanged>> virtual events.
 *
 *	For Expose and Configure, simply schedule the widget for redisplay.
 *	For Destroy events, handle the cleanup process.
 *
 *	For Focus events, set/clear the focus bit in the state field.
 *	It turns out this is impossible to do correctly in a binding script,
 *	because Tk filters out focus events with detail == NotifyInferior.
 *
 *	For Deactivate/Activate pseudo-events, set/clear the background state
 *	flag.
 */

static const unsigned CoreEventMask
    = ExposureMask
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344



345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
306
307
308
309
310
311
312

313

314
315
316
317
318
319
320
321
322














323
324



325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345







-
+
-









-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
-
-
+
+
+










-
+







	    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);
		WidgetWorldChanged(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 = {
static Tk_ClassProcs widgetClassProcs = {
    sizeof(Tk_ClassProcs),	/* size */
    WidgetWorldChanged,	/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
    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;
    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
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381







-
+







	return TCL_ERROR;

    /*
     * Allocate and initialize the widget record.
     */
    recordPtr = ckalloc(widgetSpec->recordSize);
    memset(recordPtr, 0, widgetSpec->recordSize);
    corePtr = (WidgetCore *)recordPtr;
    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;
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456







-
+







 * 	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;
    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
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







-
+


-
+






-
+







 * 	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;
    WidgetCore *corePtr = recordPtr;
    const char *baseStyleName = 0;
    Tcl_DString styleName;
    Ttk_Orient orient = TTK_ORIENT_HORIZONTAL;
    int orient = TTK_ORIENT_HORIZONTAL;
    Ttk_Layout layout;

    Tcl_DStringInit(&styleName);

    /* Prefix:
     */
    TtkGetOrientFromObj(NULL, orientObj, &orient);
    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
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







-
-







-
-
-
-









-
+














-








-
+








-
+








-
+













-
+



















-
+







}

/* 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;
    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)
{
    (void)recordPtr;
    return;
}

/* TtkWidgetDoLayout --
 * 	Default widget layoutProc.
 */
void TtkWidgetDoLayout(void *clientData)
{
    WidgetCore *corePtr = (WidgetCore *)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 = (WidgetCore *)recordPtr;
    WidgetCore *corePtr = recordPtr;
    Ttk_DrawLayout(corePtr->layout, corePtr->state, d);
}

/* TtkWidgetSize --
 * 	Default widget sizeProc()
 */
int TtkWidgetSize(void *recordPtr, int *widthPtr, int *heightPtr)
{
    WidgetCore *corePtr = (WidgetCore *)recordPtr;
    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 = (WidgetCore *)recordPtr;
    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 = (WidgetCore *)recordPtr;
    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,
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
665
666
667
668
669
670
671

672
673
674
675
676
677
678
679







-
+







 *
 * 	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;
    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


787
788
789
790
791
792
793
794
795
796
797
798
799
800
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







-
+














-
+















-
+

















-
-
+
+
-













 *	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;
    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_NewWideIntObj(Ttk_StateMatches(state,&spec)));
	    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 = (WidgetCore *)recordPtr;
    WidgetCore *corePtr = 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
    if (Tcl_GetIntFromObj(interp, objv[objc-2], &x) != TCL_OK
	    || Tcl_GetIntFromObj(interp, objv[objc-1], &y) != TCL_OK) {
    ) {
	return TCL_ERROR;
    }

    element = Ttk_IdentifyElement(corePtr->layout, x, y);
    if (element) {
	const char *elementName = Ttk_ElementName(element);
	Tcl_SetObjResult(interp,Tcl_NewStringObj(elementName,-1));
    }

    return TCL_OK;
}

/*EOF*/
Changes to generic/ttk/ttkWidget.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
113
114
115
116
117
118
119

120
121
122

123
124
125
126
127
128
129

130
131
132
133

134
135
136
137
138
139
140
141







-
+


-
+






-
+



-
+







 * 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 }
	"ttk::takefocus", Tk_Offset(WidgetCore, takeFocusPtr), -1, 0,0,0 }
#define WIDGET_TAKEFOCUS_FALSE \
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", \
	"", offsetof(WidgetCore, takeFocusPtr), TCL_INDEX_NONE, 0,0,0 }
	"", 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, TCL_INDEX_NONE,TCL_INDEX_NONE, 0, baseOptionSpecs, 0}
    {TK_OPTION_END, 0,0,0, NULL, -1,-1, 0, (ClientData)baseOptionSpecs, 0}

/* All widgets should inherit from ttkCoreOptionSpecs[].
 */
MODULE_SCOPE const Tk_OptionSpec 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
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);
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228


229
230
231
232
233
234
235







-
+













-
-







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);
	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 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);
Changes to library/bgerror.tcl.
1
2
3
4
5
6
7
8
9
10
11
12




13
14
15
16
17
18
19
1
2
3
4
5
6
7
8




9
10
11
12
13
14
15
16
17
18
19








-
-
-
-
+
+
+
+







# 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>
# Copyright (c) 1998-2000 by Ajuba Solutions.
# Copyright (c) 2007 by ActiveState Software Inc.
# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
# Copyright (c) 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]
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
1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
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.
# 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 <Button-1> {
    bind Radiobutton <1> {
	tk::ButtonDown %W
    }
    bind Radiobutton <ButtonRelease-1> {
	tk::ButtonUp %W
    }
    bind Checkbutton <Enter> {
	tk::ButtonEnter %W
    }
    bind Checkbutton <Button-1> {
    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 <Button-1> {
    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 <Button-1> {
    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 <Button-1> {
    bind Checkbutton <1> {
	tk::CheckInvoke %W
    }
    bind Radiobutton <Button-1> {
    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
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+







bind Button <FocusIn> {}
bind Button <Enter> {
    tk::ButtonEnter %W
}
bind Button <Leave> {
    tk::ButtonLeave %W
}
bind Button <Button-1> {
bind Button <1> {
    tk::ButtonDown %W
}
bind Button <ButtonRelease-1> {
    tk::ButtonUp %W
}

bind Checkbutton <FocusIn> {}
Changes to library/choosedir.tcl.
1
2
3
4
5

6
7
8
9
10
11
12
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.
# 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
114
115
116
117
118
119
120

121


122
123
124
125
126
127
128
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130







+
-
+
+








    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
    }
    if {[winfo exists $data(dirMenuBtn)]} {
    $data(dirMenuBtn) configure -textvariable {}
	$data(dirMenuBtn) configure -textvariable {}
    }

    # Return value to user
    #

    return $Priv(selectFilePath)
}

Changes to library/clrpick.tcl.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







# clrpick.tcl --
#
#	Color selection dialog for platforms that do not support a
#	standard color selection dialog.
#
# Copyright © 1996 Sun Microsystems, Inc.
# 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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
316
317
318
319
320
321
322

323
324
325
326
327
328
329







-








    # 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} {
Changes to library/comdlg.tcl.
1
2
3
4
5
6

7
8
9
10
11
12
13
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.
# 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 --
#
25
26
27
28
29
30
31
32


33
34
35
36
37
38
39
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40







-
+
+







# w = widget record to modify. Must be the pathname of a widget.
#
# specs = {
#    {-commandlineswitch resourceName ResourceClass defaultValue verifier}
#    {....}
# }
#
# flags = currently unused.
# flags = a list of flags. Currently supported flags are:
#     DONTSETDEFAULTS = skip default values setting
#
# argList = The list of  "-option value" pairs.
#
proc tclParseConfigSpec {w specs flags argList} {
    upvar #0 $w data

    # 1: Put the specs in associative arrays for faster access
59
60
61
62
63
64
65

66
67



68
69
70
71
72
73
74
60
61
62
63
64
65
66
67


68
69
70
71
72
73
74
75
76
77







+
-
-
+
+
+







	}
	return -code error -errorcode {TK VALUE_MISSING} \
	    "value for \"$cmdsw\" missing"
    }

    # 2: set the default values
    #
    if {"DONTSETDEFAULTS" ni $flags} {
    foreach cmdsw [array names cmd] {
	set data($cmdsw) $def($cmdsw)
        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] \
Changes to library/console.tcl.
1
2
3
4
5
6
7
8
9



10
11
12
13
14
15
16
1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16






-
-
-
+
+
+







# 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>
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 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

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102









103
104
105
106
107




108
109
110
111
112

113
114

115
116

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131



132
133
134
135
136
137




138
139
140
141
142
143
144



145
146
147
148
149

150
151

152
153

154
155
156
157
158
159
160
87
88
89
90
91
92
93









94
95
96
97
98
99
100
101
102
103




104
105
106
107
108
109
110
111

112
113

114
115

116
117
118
119
120
121
122
123
124
125
126
127
128



129
130
131
132
133




134
135
136
137
138
139
140
141



142
143
144
145
146
147
148

149
150

151
152

153
154
155
156
157
158
159
160







-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+




-
+

-
+

-
+












-
-
-
+
+
+


-
-
-
-
+
+
+
+




-
-
-
+
+
+




-
+

-
+

-
+







	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]
	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]
        }
	} 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>>}
	-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>>}
	-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>>}
	-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 {} }
	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
        }
	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 {
        Entry.field -sticky news -border 1 -children {
            ConsoleFrame.padding -sticky news
        }
	Entry.field -sticky news -border 1 -children {
	    ConsoleFrame.padding -sticky news
	}
    }
    ::ttk::frame .consoleframe -style ConsoleFrame

    set con [text .console -yscrollcommand [list .sb set] -setgrid true \
                 -borderwidth 0 -highlightthickness 0 -font TkConsoleFont]
		 -borderwidth 0 -highlightthickness 0 -font TkConsoleFont]
    if {[tk windowingsystem] eq "aqua"} {
        scrollbar .sb -command [list $con yview]
	scrollbar .sb -command [list $con yview]
    } else {
        ::ttk::scrollbar .sb -command [list $con yview]
	::ttk::scrollbar .sb -command [list $con yview]
    }
    pack .sb  -in .consoleframe -fill both -side right -padx 1 -pady 1
    pack $con -in .consoleframe -fill both -expand 1 -side left -padx 1 -pady 1
    pack .consoleframe -fill both -expand 1 -side left

    ConsoleBind $con

211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
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]
	set cmd [list source -encoding utf-8 $filename]
	if {[catch {consoleinterp eval $cmd} result]} {
	    ConsoleOutput stderr "$result\n"
	}
    }
}

# ::tk::ConsoleInvoke --
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286




287
288

289
290
291


292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310




311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331





332
333
334
335
336
337



338
339

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354


355
356
357
358
359
360
361
362
363
364




365
366
367
368
369
370
371
372
373
374
375
376
377
378
379









380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398








399
400
401
402
403
404
405
269
270
271
272
273
274
275

276
277
278
279
280
281
282




283
284
285
286
287

288
289


290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306




307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326





327
328
329
330
331
332
333
334



335
336
337
338

339
340
341
342
343
344
345
346
347
348
349
350
351
352


353
354
355
356
357
358
359
360




361
362
363
364
365
366
367
368
369
370









371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390








391
392
393
394
395
396
397
398
399
400
401
402
403
404
405







-
+






-
-
-
-
+
+
+
+

-
+

-
-
+
+















-
-
-
-
+
+
+
+
















-
-
-
-
-
+
+
+
+
+



-
-
-
+
+
+

-
+













-
-
+
+






-
-
-
-
+
+
+
+






-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+











-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+







# cmd -	Which action to take: prev, next, reset.

set ::tk::HistNum 1
proc ::tk::ConsoleHistory {cmd} {
    variable HistNum

    switch $cmd {
    	prev {
	prev {
	    incr HistNum -1
	    if {$HistNum == 0} {
		set cmd {history event [expr {[history nextid] -1}]}
	    } else {
		set cmd "history event $HistNum"
	    }
    	    if {[catch {consoleinterp eval $cmd} cmd]} {
    	    	incr HistNum
    	    	return
    	    }
	    if {[catch {consoleinterp eval $cmd} cmd]} {
		incr HistNum
		return
	    }
	    .console delete promptEnd end
    	    .console insert promptEnd $cmd {input stdin}
	    .console insert promptEnd $cmd {input stdin}
	    .console see end
    	}
    	next {
	}
	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
    	}
	}
	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
    if {$partial eq "normal"} {
	set temp [$w index "end - 1 char"]
	$w mark set output end
    	if {[consoleinterp eval "info exists tcl_prompt1"]} {
    	    consoleinterp eval "eval \[set tcl_prompt1\]"
    	} else {
    	    puts -nonewline [EvalAttached $::tk::console::defaultPrompt]
    	}
	if {[consoleinterp eval "info exists tcl_prompt1"]} {
	    consoleinterp eval "eval \[set tcl_prompt1\]"
	} else {
	    puts -nonewline [EvalAttached $::tk::console::defaultPrompt]
	}
    } else {
	set temp [$w index output]
	$w mark set output end
    	if {[consoleinterp eval "info exists tcl_prompt2"]} {
    	    consoleinterp eval "eval \[set tcl_prompt2\]"
    	} else {
	if {[consoleinterp eval "info exists tcl_prompt2"]} {
	    consoleinterp eval "eval \[set tcl_prompt2\]"
	} else {
	    puts -nonewline "> "
    	}
	}
    }
    flush stdout
    $w mark set output $temp
    ::tk::TextSetCursor $w end
    $w mark set promptEnd insert
    $w mark gravity promptEnd left
    ::tk::console::ConstrainBuffer $w $::tk::console::maxLines
    $w see end
}

# Copy selected text from the console
proc ::tk::console::Copy {w} {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        clipboard clear -displayof $w
        clipboard append -displayof $w $data
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
    }
}
# Copies selected text. If the selection is within the current active edit
# region then it will be cut, if not it is only copied.
proc ::tk::console::Cut {w} {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        clipboard clear -displayof $w
        clipboard append -displayof $w $data
        if {[$w compare sel.first >= output]} {
            $w delete sel.first sel.last
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
	if {[$w compare sel.first >= output]} {
	    $w delete sel.first sel.last
	}
    }
}
# Paste text from the clipboard
proc ::tk::console::Paste {w} {
    catch {
        set clip [::tk::GetSelection $w CLIPBOARD]
        set list [split $clip \n\r]
        tk::ConsoleInsert $w [lindex $list 0]
        foreach x [lrange $list 1 end] {
            $w mark set insert {end - 1c}
            tk::ConsoleInsert $w "\n"
            tk::ConsoleInvoke
            tk::ConsoleInsert $w $x
        }
	set clip [::tk::GetSelection $w CLIPBOARD]
	set list [split $clip \n\r]
	tk::ConsoleInsert $w [lindex $list 0]
	foreach x [lrange $list 1 end] {
	    $w mark set insert {end - 1c}
	    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
        }
	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
428
429
430
431
432
433
434




435
436
437
438
439
440
441
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445







+
+
+
+







    # 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}
    if {[tk windowingsystem] eq "aqua"} {
	bind Console <Command-Key> {# nothing}
	bind Console <Mod4-Key> {# nothing}
    }

    foreach {ev key} {
	<<Console_NextImmediate>>	<Control-n>
	<<Console_PrevImmediate>>	<Control-p>
	<<Console_PrevSearch>>		<Control-r>
	<<Console_NextSearch>>		<Control-s>

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
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







-
+












-
-
-
-
+
+
+
+





-
-
-
-
-
+
+
+
+
+







    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 .]
	destroy {*}[winfo children .]
	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
	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
	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
    }
Changes to library/demos/check.tcl.
61
62
63
64
65
66
67
68
69
70
71




61
62
63
64
65
66
67




68
69
70
71







-
-
-
-
+
+
+
+
	} else {
	    set safety none
	}
    }
    set in_check 0
}

trace variable wipers w tristate_check
trace variable brakes w tristate_check
trace variable sober  w tristate_check
trace variable safety w tristate_check
trace add variable wipers write tristate_check
trace add variable brakes write tristate_check
trace add variable sober  write tristate_check
trace add variable safety write tristate_check
Changes to library/demos/combo.tcl.
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
39
40
41
42
43
44
45

46

47
48
49
50
51
52
53







-
+
-







    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::combobox $w.c1.c -textvariable firstValue
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]} {
Changes to library/demos/cscroll.tcl.
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35







-
+







pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.grid
scrollbar $w.hscroll -orient horiz -command "$c xview"
scrollbar $w.hscroll -orient horizontal -command "$c xview"
scrollbar $w.vscroll -command "$c yview"
canvas $c -relief sunken -borderwidth 2 -scrollregion {-11c -11c 50c 20c} \
	-xscrollcommand "$w.hscroll set" \
	-yscrollcommand "$w.vscroll set"
pack $w.grid -expand yes -fill both -padx 1 -pady 1
grid rowconfig    $w.grid 0 -weight 1 -minsize 0
grid columnconfig $w.grid 0 -weight 1 -minsize 0
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92

93
94

95
96
97
98
99
100
101
102
103
104
105
106

107
108

109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91

92
93

94
95
96
97
98
99
100
101
102
103
104
105

106
107

108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124







-
+









-
+

-
+











-
+

-
+








-
+







    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.
    # The following code ensures 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
	    %W yview scroll [expr {%D/-12}] units
	} else {
	    %W yview scroll [expr {(%D-2)/-3}] units
	    %W yview scroll [expr {(%D-11)/-12}] 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
	    %W xview scroll [expr {%D/-12}] units
	} else {
	    %W xview scroll [expr {(%D-2)/-3}] units
	    %W xview scroll [expr {(%D-11)/-12}] 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/
    #	https://linuxreviews.org/HOWTO_change_the_mouse_speed_in_X
    bind $c <Button-4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
	}
    }
    bind $c <Shift-Button-4> {
	if {!$tk_strictMotif} {
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
132
133
134
135
136
137
138

139
140
141
142
143
144
145







-







    }
    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}]
    }
Changes to library/demos/entry1.tcl.
21
22
23
24
25
26
27
28

29
30
31
32
33
34
21
22
23
24
25
26
27

28
29
30
31
32
33
34







-
+







## 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
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.
23
24
25
26
27
28
29
30

31
32
33
34

35
36
37
38

39
40
41
42
43
44
45
46
47
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 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 \
ttk::scrollbar $w.frame.s1 -orient horizontal -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 \
ttk::scrollbar $w.frame.s2 -orient horizontal -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 \
ttk::scrollbar $w.frame.s3 -orient horizontal -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
Changes to library/demos/floor.tcl.
58
59
60
61
62
63
64

65
66
67
68
69
70
71
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72







+







    $w move floor1 2c 2c
    $w move floor2 1c 1c

    # Create items for the room entry and its label.

    $w create window 600 100 -anchor w -window $w.entry
    $w create text 600 100 -anchor e -text "Room: "

    $w config -scrollregion [$w bbox all]
}

# newRoom --
# This procedure is invoked whenever the mouse enters a room
# in the floorplan.  It changes tags so that the current room is
# highlighted.
329
330
331
332
333
334
335
336

337
338
339
340

341
342
343
344

345
346
347
348

349
350
351
352

353
354
355
356

357
358
359
360

361
362
363
364

365
366
367
368

369
370
371
372

373
374
375
376

377
378
379
380

381
382
383
384

385
386
387
388

389
390
391
392

393
394
395
396

397
398
399
400

401
402
403
404

405
406
407
408

409
410
411
412

413
414
415
416

417
418
419
420

421
422
423
424

425
426
427
428

429
430
431
432

433
434
435
436

437
438
439
440

441
442
443
444

445
446
447
448

449
450
451
452

453
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
330
331
332
333
334
335
336

337
338
339
340

341
342
343
344

345
346
347
348

349
350
351
352

353
354
355
356

357
358
359
360

361
362
363
364

365
366
367
368

369
370
371
372

373
374
375
376

377
378
379
380

381
382
383
384

385
386
387
388

389
390
391
392

393
394
395
396

397
398
399
400

401
402
403
404

405
406
407
408

409
410
411
412

413
414
415
416

417
418
419
420

421
422
423
424

425
426
427
428

429
430
431
432

433
434
435
436

437
438
439
440

441
442
443
444

445
446
447
448

449
450
451
452

453
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







-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+







#
# 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 i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -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 i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -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 i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -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 i [$w create polygon 42 389 42 337 1 337 1 389 -fill {} -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 i [$w create polygon 59 389 59 385 90 385 90 337 44 337 44 389 -fill {} -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 i [$w create polygon 51 300 51 253 6 253 6 300 -fill {} -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 i [$w create polygon 98 248 98 309 79 309 79 248 -fill {} -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 i [$w create polygon 51 251 51 204 6 204 6 251 -fill {} -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 i [$w create polygon 6 156 51 156 51 203 6 203 -fill {} -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 i [$w create polygon 85 169 79 169 79 192 85 192 -fill {} -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 i [$w create polygon 77 302 77 168 53 168 53 302 -fill {} -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 i [$w create polygon 51 155 51 115 6 115 6 155 -fill {} -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 i [$w create polygon 95 115 53 115 53 168 95 168 -fill {} -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 i [$w create polygon 87 113 87 27 10 27 10 113 -fill {} -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 i [$w create polygon 89 91 128 91 128 113 89 113 -fill {} -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 i [$w create polygon 178 128 178 132 216 132 216 91 163 91 163 112 149 112 149 128 -fill {} -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 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 {} -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 i [$w create polygon 138 169 154 169 154 191 138 191 -fill {} -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 i [$w create polygon 99 300 126 300 126 309 99 309 -fill {} -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 i [$w create polygon 128 299 128 309 150 309 150 248 99 248 99 299 -fill {} -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 i [$w create polygon 174 309 174 300 152 300 152 309 -fill {} -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 i [$w create polygon 176 299 176 309 216 309 216 248 152 248 152 299 -fill {} -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 i [$w create polygon 138 385 138 337 91 337 91 385 -fill {} -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 i [$w create polygon 256 337 140 337 140 385 256 385 -fill {} -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 i [$w create polygon 300 353 300 329 260 329 260 353 -fill {} -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 i [$w create polygon 314 135 314 170 306 170 306 246 177 246 177 135 -fill {} -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 i [$w create polygon 217 248 301 248 301 326 257 326 257 310 217 310 -fill {} -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 i [$w create polygon 396 188 377 188 377 169 316 169 316 131 396 131 -fill {} -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 i [$w create polygon 397 226 407 226 407 189 377 189 377 246 397 246 -fill {} -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 i [$w create polygon 399 187 409 187 409 207 474 207 474 164 399 164 -fill {} -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 i [$w create polygon 409 209 409 229 399 229 399 253 486 253 486 239 474 239 474 209 -fill {} -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 i [$w create polygon 501 164 501 174 495 174 495 188 490 188 490 204 476 204 476 164 -fill {} -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 i [$w create polygon 497 176 513 176 513 204 492 204 492 190 497 190 -fill {} -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 i [$w create polygon 476 237 476 206 513 206 513 254 488 254 488 237 -fill {} -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 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 {} -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 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 {} -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 i [$w create polygon 397 255 486 255 486 276 397 276 -fill {} -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 i [$w create polygon 510 309 486 309 486 255 530 255 552 277 561 277 561 325 510 325 -fill {} -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 i [$w create polygon 696 281 740 281 740 387 642 387 642 389 561 389 561 277 696 277 -fill {} -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 i [$w create polygon 742 387 742 281 800 281 800 387 -fill {} -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 i [$w create polygon 800 168 800 280 699 280 699 168 -fill {} -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 i [$w create polygon 726 131 726 166 800 166 800 131 -fill {} -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 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 {} -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 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 {} -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 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 {} -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 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 {} -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 i [$w create polygon 257 336 77 336 6 336 6 301 77 301 77 310 257 310 -fill {} -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 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 {} -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}
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
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







-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+







#
# 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 i [$w create polygon 748 188 755 188 755 205 758 205 758 222 800 222 800 168 748 168 -fill {} -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 i [$w create polygon 726 188 746 188 746 166 800 166 800 131 726 131 -fill {} -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 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 {} -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 i [$w create polygon 694 279 643 279 643 314 694 314 -fill {} -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 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 {} -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 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 {} -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 i [$w create polygon 51 277 6 277 6 338 51 338 -fill {} -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 i [$w create polygon 557 276 486 276 486 309 510 309 510 325 557 325 -fill {} -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 i [$w create polygon 560 389 599 389 599 326 560 326 -fill {} -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 i [$w create polygon 601 389 601 326 643 326 643 389 -fill {} -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 i [$w create polygon 688 316 645 316 645 365 688 365 -fill {} -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 i [$w create polygon 802 367 759 367 759 226 802 226 -fill {} -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 i [$w create polygon 755 262 755 314 717 314 717 262 -fill {} -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 i [$w create polygon 755 316 689 316 689 365 755 365 -fill {} -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 i [$w create polygon 755 206 717 206 717 261 755 261 -fill {} -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 i [$w create polygon 695 277 643 277 643 206 695 206 -fill {} -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 i [$w create polygon 676 135 676 185 724 185 724 135 -fill {} -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 i [$w create polygon 675 135 635 135 635 145 628 145 628 185 675 185 -fill {} -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 i [$w create polygon 626 143 633 143 633 135 572 135 572 143 579 143 579 185 626 185 -fill {} -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 i [$w create polygon 557 135 571 135 571 145 578 145 578 185 527 185 527 131 557 131 -fill {} -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 i [$w create polygon 476 249 557 249 557 205 476 205 -fill {} -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 i [$w create polygon 476 164 486 164 486 131 525 131 525 185 476 185 -fill {} -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 i [$w create polygon 476 186 495 186 495 204 476 204 -fill {} -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 i [$w create polygon 474 207 409 207 409 187 399 187 399 164 474 164 -fill {} -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 i [$w create polygon 399 228 399 253 474 253 474 209 409 209 409 228 -fill {} -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 i [$w create polygon 397 246 397 226 407 226 407 189 377 189 377 246 -fill {} -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 i [$w create polygon 377 169 316 169 316 131 397 131 397 188 377 188 -fill {} -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 i [$w create polygon 234 198 306 198 306 249 234 249 -fill {} -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 i [$w create polygon 270 179 306 179 306 170 314 170 314 135 270 135 -fill {} -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 i [$w create polygon 268 179 221 179 221 135 268 135 -fill {} -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 i [$w create polygon 177 179 219 179 219 135 177 135 -fill {} -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 i [$w create polygon 299 327 349 327 349 284 341 284 341 276 299 276 -fill {} -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 i [$w create polygon 234 276 297 276 297 327 257 327 257 338 234 338 -fill {} -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 i [$w create polygon 256 385 256 340 212 340 212 385 -fill {} -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 i [$w create polygon 210 340 164 340 164 385 210 385 -fill {} -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 i [$w create polygon 115 340 162 340 162 385 115 385 -fill {} -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 i [$w create polygon 89 228 89 156 53 156 53 228 -fill {} -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 i [$w create polygon 89 169 97 169 97 190 89 190 -fill {} -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 i [$w create polygon 89 156 89 168 95 168 95 135 53 135 53 156 -fill {} -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 i [$w create polygon 51 179 51 135 6 135 6 179 -fill {} -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 i [$w create polygon 51 227 6 227 6 180 51 180 -fill {} -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 i [$w create polygon 51 275 6 275 6 229 51 229 -fill {} -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 i [$w create polygon 114 340 67 340 67 385 114 385 -fill {} -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 i [$w create polygon 59 389 59 385 65 385 65 340 1 340 1 389 -fill {} -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 i [$w create polygon 393 309 350 309 350 282 342 282 342 276 393 276 -fill {} -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 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 {} -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 i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -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 i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -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 i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -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 i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -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 i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -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}
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
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







-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+



-
+







#
# 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 i [$w create polygon 89 228 89 180 70 180 70 228 -fill {} -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 i [$w create polygon 115 368 162 368 162 323 115 323 -fill {} -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 i [$w create polygon 164 323 164 368 211 368 211 323 -fill {} -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 i [$w create polygon 256 368 212 368 212 323 256 323 -fill {} -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 i [$w create polygon 244 276 297 276 297 327 260 327 260 321 244 321 -fill {} -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 i [$w create polygon 251 219 251 203 244 203 244 219 -fill {} -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 i [$w create polygon 251 249 244 249 244 232 251 232 -fill {} -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 i [$w create polygon 223 135 223 179 177 179 177 135 -fill {} -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 i [$w create polygon 114 368 114 323 67 323 67 368 -fill {} -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 i [$w create polygon 23 277 23 321 68 321 68 277 -fill {} -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 i [$w create polygon 23 229 68 229 68 275 23 275 -fill {} -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 i [$w create polygon 68 227 23 227 23 180 68 180 -fill {} -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 i [$w create polygon 95 179 95 135 23 135 23 179 -fill {} -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 i [$w create polygon 99 226 99 204 91 204 91 226 -fill {} -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 i [$w create polygon 91 202 99 202 99 180 91 180 -fill {} -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 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 {} -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 i [$w create polygon 65 368 58 368 58 389 1 389 1 333 23 333 23 323 65 323 -fill {} -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 i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -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 i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -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 i [$w create polygon 274 194 274 221 306 221 306 194 -fill {} -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 i [$w create polygon 306 222 274 222 274 249 306 249 -fill {} -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 i [$w create polygon 263 179 224 179 224 135 263 135 -fill {} -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 i [$w create polygon 314 169 306 169 306 192 273 192 264 181 264 135 314 135 -fill {} -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 i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -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 i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -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 i [$w create polygon 350 284 376 284 376 276 397 276 397 309 350 309 -fill {} -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 i [$w create polygon 272 203 272 249 252 249 252 230 244 230 244 221 252 221 252 203 -fill {} -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 i [$w create polygon 299 276 299 327 349 327 349 284 341 284 341 276 -fill {} -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 i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -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 i [$w create polygon 397 246 377 246 377 185 397 185 -fill {} -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 i [$w create polygon 316 131 316 169 377 169 377 185 397 185 397 131 -fill {} -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 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 {} -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 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 {} -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}
1364
1365
1366
1367
1368
1369
1370
1371

1365
1366
1367
1368
1369
1370
1371

1372







-
+
    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"
trace add variable currentRoom write "roomChanged $c"
Changes to library/demos/goldberg.tcl.
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101







-














+







array set speed {1 10 2 20 3 50 4 80 5 100 6 150 7 200 8 300 9 400 10 500}

set MSTART 0; set MGO 1; set MPAUSE 2; set MSSTEP 3; set MBSTEP 4; set MDONE 5
set S(mode) $::MSTART

# Colors for everything
set C(fg) black
set C(bg) gray75
set C(bg) cornflowerblue

set C(0) white;		set C(1a) darkgreen;	set C(1b) yellow
set C(2) red;		set C(3a) green;	set C(3b) darkblue
set C(4) $C(fg);	set C(5a) brown;	set C(5b) white
set C(6) magenta;	set C(7) green;		set C(8) $C(fg)
set C(9) blue4;		set C(10a) white;	set C(10b) cyan
set C(11a) yellow;	set C(11b) mediumblue;	set C(12) tan2
set C(13a) yellow;	set C(13b) red;		set C(14) white
set C(15a) green;	set C(15b) yellow;	set C(16) gray65
set C(17) \#A65353;	set C(18) $C(fg);	set C(19) gray50
set C(20) cyan;		set C(21) gray65;	set C(22) $C(20)
set C(23a) blue;	set C(23b) red;		set C(23c) yellow
set C(24a) red;		set C(24b) white;
set C(24c) black;	set C(26) $C(0);

proc DoDisplay {w} {
    global S C

    ttk::frame $w.ctrl -relief ridge -borderwidth 2 -padding 5
    pack [frame $w.screen -bd 2 -relief raised] \
	    -side left -fill both -expand 1
109
110
111
112
113
114
115
116

117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158



159
160
161
162
163
164
165
109
110
111
112
113
114
115

116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155



156
157
158
159
160
161
162
163
164
165







-
+

-
+




















-
+
















-
-
-
+
+
+







    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
	ttk::button $w.show -text "\xbb" -command [list ShowCtrl $w] -width 2
    } else {
	button $w.show -text "»" -command [list ShowCtrl $w] -width 2 -highlightbackground $C(bg)
	button $w.show -text "\xbb" -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
    ttk::button $w.start -text "Start" -command [list DoButton $w 0]
    ttk::checkbutton $w.pause -text "Pause" -command [list DoButton $w 1] \
	    -variable S(pause)
    ttk::button $w.step -text "Single Step" -command [list DoButton $w 2]
    ttk::button $w.bstep -text "Big Step" -command [list DoButton $w 4]
    ttk::button $w.reset -text "Reset" -command [list DoButton $w 3]
    ttk::labelframe $w.details
    raise $w.details
    set S(details) 0
    ttk::checkbutton $w.details.cb -text "Details" -variable S(details)
    ttk::labelframe $w.message -text "Message"
    ttk::entry $w.message.e -textvariable S(message) -justify center
    ttk::labelframe $w.speed -text "Speed: 0"
    ttk::scale $w.speed.scale -orient h -from 1 -to 10 -variable S(speed)
    ttk::scale $w.speed.scale -orient horizontal -from 1 -to 10 -variable S(speed)
    ttk::button $w.about -text About -command [list About $w]

    grid $w.start -in $w.ctrl -row 0 -sticky ew
    grid rowconfigure $w.ctrl 1 -minsize 10
    grid $w.pause -in $w.ctrl -row 2 -sticky ew
    grid $w.step  -in $w.ctrl -sticky ew -pady 2
    grid $w.bstep -in $w.ctrl -sticky ew
    grid $w.reset -in $w.ctrl -sticky ew -pady 2
    grid rowconfigure $w.ctrl 10 -minsize 18
    grid $w.details -in $w.ctrl -row 11 -sticky ew
    grid rowconfigure $w.ctrl 11 -minsize 20
    $w.details configure -labelwidget $w.details.cb
    grid [ttk::frame $w.details.b -height 1]	;# Work around minor bug
    raise $w.details
    raise $w.details.cb
    grid rowconfigure $w.ctrl 50 -weight 1
    trace variable ::S(mode) w	  [list ActiveGUI $w]
    trace variable ::S(details) w [list ActiveGUI $w]
    trace variable ::S(speed) w	  [list ActiveGUI $w]
    trace add variable ::S(mode) write	  [list ActiveGUI $w]
    trace add variable ::S(details) write [list ActiveGUI $w]
    trace add variable ::S(speed) write	  [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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210

211
212
213
214
215
216
217
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208

209
210
211
212
213
214
215
216







-


















-
+


-
+







    destroy $btns
}

proc DoDetailFrame {w} {
    set w2 $w.details.f
    ttk::frame $w2

    set bd 2
    ttk::label $w2.l -textvariable S(cnt) -background white
    grid $w2.l - - - -sticky ew -row 0
    for {set i 1} {1} {incr i} {
	if {[info procs "Move$i"] eq ""} break
	ttk::label $w2.l$i -text $i -anchor e -width 2 -background white
	ttk::label $w2.ll$i -textvariable STEP($i) -width 5 -background white
	set row [expr {($i + 1) / 2}]
	set col [expr {(($i + 1) & 1) * 2}]
	grid $w2.l$i -sticky ew -row $row -column $col
	grid $w2.ll$i -sticky ew -row $row -column [incr col]
    }
    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 "»"
	$w.show config -text "\xbb"
    } else {
	pack $w.ctrl -side right -fill both -ipady 5
	$w.show config -text "»"
	$w.show config -text "\xab"
    }
}

proc DrawAll {w} {
    ResetStep
    $w.c delete all
    for {set i 0} {1} {incr i} {
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+








proc Go {w {who {}}} {
    global S speed animationCallbacks MGO MPAUSE MSSTEP MBSTEP

    set now [clock clicks -milliseconds]
    catch {after cancel $animationCallbacks(goldberg)}
    if {$who ne ""} {				;# Start here for debugging
	set S(active) $who;
	set S(active) $who
	set S(mode) $MGO
    }
    if {$S(mode) == -1} return			;# Debugging
    set n 0
    if {$S(mode) != $MPAUSE} {			;# Not paused
	set n [NextStep $w]			;# Do the next move
    }
1582
1583
1584
1585
1586
1587
1588

1589
1590
1591
1592
1593
1594
1595
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595







+







	    494 627 548 613 548 613 480 574 577 473 577 473 474 538 445 508
	    431 441 431 440 400 502 347 465 347 465
	}
	$w.c create poly $xy -tag I24 -fill $::C(24b) -outline $::C(24a) \
		-width 10 -smooth 1
	set msg [subst $S(message)]
	$w.c create text [Centroid $w I24] -text $msg -tag {I24 I24t} \
		-fill $::C(24c) \
		-justify center -font {{Times Roman} 18 bold}
	return 1
    }

    $w.c itemconfig I24t -font [list {Times Roman} [expr {18 + 6*$step}] bold]
    $w.c move I24 0 -60
    $w.c scale I24 {*}[Centroid $w I24] 1.25 1.25
1615
1616
1617
1618
1619
1620
1621

1622
1623
1624
1625
1626
1627
1628
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629







+







proc Move26 {w {step {}}} {
    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 \
		-fill $::C(26) \
		-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
Changes to library/demos/images/earth.gif.

cannot compute difference between binary files

Changes to library/demos/items.tcl.
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42







-
+







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"
ttk::scrollbar $w.frame.hscroll -orient horizontal -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
Changes to library/demos/knightstour.tcl.
1

2
3
4
5
6
7
8

1
2
3
4
5
6
7
8
-
+







# Copyright © 2008 Pat Thoyts <patthoyts@users.sourceforge.net>
# 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.
#
201
202
203
204
205
206
207
208

209
210
211

212
213
214
215
216
217
218
201
202
203
204
205
206
207

208
209
210

211
212
213
214
215
216
217
218







-
+


-
+







                            [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 "" \
        $c create text 0 0 -font KnightFont -text "\u265e" \
            -anchor nw -tags knight -fill black -activefill "#600000"
    } else {
        # On X11 we cannot reliably tell if the  glyph is available
        # On X11 we cannot reliably tell if the \u265e 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"
Changes to library/demos/menu.tcl.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
14
15
16
17
18
19
20

21
22
23
24
25
26
27







-







toplevel $w
wm title $w "Menu Demonstration"
wm iconname $w "menu"
positionWindow $w

label $w.msg -font $font -wraplength 4i -justify left
if {[tk windowingsystem] eq "aqua"} {
    catch {set origUseCustomMDEF $::tk::mac::useCustomMDEF; set ::tk::mac::useCustomMDEF 1}
    $w.msg configure -text "This window has a menubar with cascaded menus.  You can invoke entries with an accelerator by typing Command+x, where \"x\" is the character next to the command key symbol. The rightmost menu can be torn off into a palette by selecting the first item in the menu."
} else {
    $w.msg configure -text "This window contains a menubar with cascaded menus.  You can post a menu from the keyboard by typing Alt+x, where \"x\" is the character underlined on the menu.  You can then traverse among the menus using the arrow keys.  When a menu is posted, you can invoke the current entry by typing space, or you can invoke any entry by typing its underlined character.  If a menu entry has an accelerator, you can invoke the entry without posting the menu just by typing the accelerator. The rightmost menu can be torn off into a palette by selecting the first item in the menu."
}
pack $w.msg -side top

set menustatus "    "
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66

67
68
69
70
71
72
73
51
52
53
54
55
56
57

58
59
60
61
62
63
64

65
66
67
68
69
70
71
72







-
+






-
+








set m $w.menu.basic
$w.menu add cascade -label "Basic" -menu $m -underline 0
menu $m -tearoff 0
$m add command -label "Long entry that does nothing"
if {[tk windowingsystem] eq "aqua"} {
    set modifier Command
} elseif {[tk windowingsystem] == "win32"} {
} elseif {[tk windowingsystem] eq "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
	    -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" \
127
128
129
130
131
132
133
134

135
136


137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153



154
155
156















157
158
159
160
161
162
163
164
165
166
167
168
169
170
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144







145
146
147
148
149
150



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177









-
+


+
+







-
-
-
-
-
-
-



+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












-
-
	    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}} {
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\""]
}
set emojiLabel [encoding convertfrom utf-8 "\xF0\x9F\x98\x8D Make friends"]
$m add command -label $emojiLabel -command [list puts "Menu labels can include non-BMP characters."]
$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
if {[tk windowingsystem] eq "aqua"} {
    # Aqua ignores the -background and -foreground options, but a compound
    # button can be used for selecting colors.
foreach i {red orange yellow green blue} {
    $m add command -label $i -background $i -command [list \
	    puts "You invoked \"$i\"" ]
    foreach i {red orange yellow green blue} {
	image create photo image_$i -height 16 -width 16
	image_$i put black -to 0 0 16 1
	image_$i put black -to 0 1 1 16
	image_$i put black -to 0 15 16 16
	image_$i put black -to 15 1 16 16
	image_$i put $i -to 1 1 15 15
	$m add command -label $i -image image_$i -compound left -command [list \
	puts "You invoked \"$i\"" ]
    }
} else {
    foreach i {red orange yellow green blue} {
	$m add command -label $i -background $i -command [list \
	puts "You invoked \"$i\"" ]
    }
}

$w configure -menu $w.menu

bind Menu <<MenuSelect>> {
    global $menustatus
    if {[catch {%W entrycget active -label} label]} {
	set label "    "
    }
    set menustatus $label
    update idletasks
}

if {[tk windowingsystem] eq "aqua"} {catch {set ::tk::mac::useCustomMDEF $origUseCustomMDEF}}
Changes to library/demos/menubu.tcl.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
14
15
16
17
18
19
20

21
22
23
24
25
26
27







-







toplevel $w
wm title $w "Menu Button Demonstration"
wm iconname $w "menubutton"
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
82
83
84
85
86
87
88
89
90
81
82
83
84
85
86
87









-
-
}
$m configure -tearoff 1
foreach i {Black gray75 gray50 White} {
	$m entryconfigure $i -columnbreak 1
}

pack $body.buttons.colors -side left -padx 25 -pady 25

if {[tk windowingsystem] eq "aqua"} {catch {set ::tk::mac::useCustomMDEF $origUseCustomMDEF}}
Changes to library/demos/pendulum.tcl.
46
47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
46
47
48
49
50
51
52


53
54
55
56
57
58
59
60
61







-
-
+
+







$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
$w.k create text 0 0 -anchor ne -text "\u03b8" -tags label_theta
$w.k create text 0 0 -anchor ne -text "\u03b4\u03b8" -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
78
79
80
81
82
83
84
85
86


87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
78
79
80
81
82
83
84


85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102







-
-
+
+








-
+







	set Theta  [expr {atan2($x2, $y2) * 180/$pi}]
    } else {
	set angle [expr {$Theta * $pi/180}]
	set x [expr {$home + $length*sin($angle)}]
	set y [expr {25    + $length*cos($angle)}]
    }
    $canvas coords rod $home 25 $x $y
    $canvas coords bob \
	    [expr {$x-15}] [expr {$y-15}] [expr {$x+15}] [expr {$y+15}]
    $canvas coords bob [expr {$x - 15}] [expr {$y - 15}] \
	    [expr {$x + 15}] [expr {$y + 15}]
}
showPendulum $w.c

# Update the phase-space graph according to the current angle and the
# rate at which the angle is changing (the first derivative with
# respect to time.)
proc showPhase {canvas} {
    global Theta dTheta points psw psh
    lappend points [expr {$Theta+$psw}] [expr {-20*$dTheta+$psh}]
    lappend points [expr {$Theta + $psw}] [expr {-20*$dTheta + $psh}]
    if {[llength $points] > 100} {
    	 set points [lrange $points end-99 end]
    }
    for {set i 0} {$i<100} {incr i 10} {
	set list [lrange $points end-[expr {$i-1}] end-[expr {$i-12}]]
	if {[llength $list] >= 4} {
	    $canvas coords graph$i $list
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138




139
140
141
142
143
144
145
123
124
125
126
127
128
129

130
131
132
133
134




135
136
137
138
139
140
141
142
143
144
145







-
+




-
-
-
-
+
+
+
+







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
    %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}]
    %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/puzzle.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







# puzzle.tcl --
#
# This demonstration script creates a 15-puzzle game using a collection
# of buttons.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

# puzzleSwitch --
# This procedure is invoked when the user clicks on a particular button;
# if the button is next to the empty space, it moves the button into th
# if the button is next to the empty space, it moves the button into the
# empty space.

proc puzzleSwitch {w num} {
    global xpos ypos
    if {(($ypos($num) >= ($ypos(space) - .01))
	    && ($ypos($num) <= ($ypos(space) + .01))
	    && ($xpos($num) >= ($xpos(space) - .26))
Changes to library/demos/rolodex.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20












-
+







#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# rolodex --
# This script was written as an entry in Tom LaStrange's rolodex
# benchmark.  It creates something that has some of the look and
# feel of a rolodex program, although it's lifeless and doesn't
# actually do the rolodex application.

package require Tk

foreach i [winfo child .] {
foreach i [winfo children .] {
    catch {destroy $i}
}

set version 1.2

#------------------------------------------
# Phase 0: create the front end.
Changes to library/demos/spin.tcl.
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48

49
50
51
52
53
34
35
36
37
38
39
40

41
42
43
44




45












-
+



-
-
-
-
+
-
-
-
-
-

set australianCities {
    Canberra Sydney Melbourne Perth Adelaide Brisbane
    Hobart Darwin "Alice Springs"
}

spinbox $w.s1 -from 1 -to 10 -width 10 -validate key \
	-vcmd {string is integer %P}
	-validatecommand {string is integer %P}
spinbox $w.s2 -from 0 -to 3 -increment .5 -format %05.2f -width 10
spinbox $w.s3 -values $australianCities -width 10

#entry $w.e1
#entry $w.e2
#entry $w.e3
pack $w.s1 $w.s2 $w.s3 -side top -pady 5 -padx 10 ;#-fill x
pack $w.s1 $w.s2 $w.s3 -side top -pady 5 -padx 10

#$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/toolbar.tcl.
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







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\
	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."

Changes to library/demos/ttkbut.tcl.
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27







-
+







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."
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 happiness}]\
	-side bottom -fill x

## Add buttons for setting the theme
Changes to library/demos/ttkprogress.tcl.
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25







-
+







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."
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
Added library/demos/ttkspin.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# ttkspin.tcl --
#
# This demonstration script creates several Ttk spinbox widgets.

if {![info exists widgetDemo]} {
    error "This script should be run from the \"widget\" demo."
}

package require Tk

set w .ttkspin
catch {destroy $w}
toplevel $w
wm title $w "Themed Spinbox Demonstration"
wm iconname $w "ttkspin"
positionWindow $w

label $w.msg -font $font -wraplength 5i -justify left -text "Three different\
	themed spin-boxes 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 values that are too large to fit in the\
	window all at once, you can scan through the value by dragging with\
	mouse button2 pressed.  Note that the first spin-box will only permit\
	you to type in integers, and the third selects from a list of\
	Australian cities."
pack $w.msg -side top

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

set australianCities {
    Canberra Sydney Melbourne Perth Adelaide Brisbane
    Hobart Darwin "Alice Springs"
}

ttk::spinbox $w.s1 -from 1 -to 10 -width 10 -validate key \
	-validatecommand {string is integer %P}
ttk::spinbox $w.s2 -from 0 -to 3 -increment .5 -format %05.2f -width 10
ttk::spinbox $w.s3 -values $australianCities -width 10

$w.s1 set 1
$w.s2 set 00.00
$w.s3 set Canberra

pack $w.s1 $w.s2 $w.s3 -side top -pady 5 -padx 10
Changes to library/demos/unicodeout.tcl.
17
18
19
20
21
22
23
24



25
26
27
28
29
30
31
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33







-
+
+
+







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."
	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

## The frame that will contain the sample texts.
92
93
94
95
96
97
98
99



100
101
102



103
104
105
106
107






108
109
110


111
112
113


114
115
116
117
118
119









120

121





122
123
124
125
126
94
95
96
97
98
99
100

101
102
103
104
105

106
107
108
109




110
111
112
113
114
115
116
117

118
119
120
121

122
123
124





125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145







-
+
+
+


-
+
+
+

-
-
-
-
+
+
+
+
+
+


-
+
+


-
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+

+
-
+
+
+
+
+





set oldCursor [$w cget -cursor]
$w conf -cursor watch
update

## Add the samples...
if {[usePresentationFormsFor Arabic]} {
    # Using presentation forms (pre-layouted)
    addSample $w Arabic "ﺔﻴﺑﺮﻌﻟﺍ ﺔﻤﻠﻜﻟﺍ"
    addSample $w Arabic \
	    "\uFE94\uFEF4\uFE91\uFEAE\uFECC\uFEDF\uFE8D " \
	    "\uFE94\uFEE4\uFEE0\uFEDC\uFEDF\uFE8D"
} else {
    # Using standard text characters
    addSample $w Arabic "الكلمة العربية"
    addSample $w Arabic \
	    "\u0627\u0644\u0643\u0644\u0645\u0629 " \
	    "\u0627\u0644\u0639\u0631\u0628\u064A\u0629"
}
addSample $w "Trad. Chinese"  "中國的漢字"
addSample $w "Simpl. Chinese" "汉语"
addSample $w French "Langue française"
addSample $w Greek "Ελληνική γλώσσα"
addSample $w "Trad. Chinese"  "\u4E2D\u570B\u7684\u6F22\u5B57"
addSample $w "Simpl. Chinese" "\u6C49\u8BED"
addSample $w French "Langue fran\xE7aise"
addSample $w Greek \
	"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AE " \
	"\u03B3\u03BB\u03CE\u03C3\u03C3\u03B1"
if {[usePresentationFormsFor Hebrew]} {
    # Visual order (pre-layouted)
    addSample $w Hebrew "תירבע בתכ"
    addSample $w Hebrew \
	    "\u05EA\u05D9\u05E8\u05D1\u05E2 \u05D1\u05EA\u05DB"
} else {
    # Standard logical order
    addSample $w Hebrew "כתב עברית"
    addSample $w Hebrew \
	    "\u05DB\u05EA\u05D1 \u05E2\u05D1\u05E8\u05D9\u05EA"
}
addSample $w Hindi "हिन्दी भाषा"
addSample $w Icelandic "Íslenska"
addSample $w Japanese "日本語のひらがな, 漢字とカタカナ"
addSample $w Korean "대한민국의 한글"
addSample $w Russian "Русский язык"
addSample $w Hindi \
    "\u0939\u093F\u0928\u094D\u0926\u0940 \u092D\u093E\u0937\u093E"
addSample $w Icelandic "\xCDslenska"
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"
if {([tk windowingsystem] ne "x11") || (![catch {tk::pkgconfig get fontsystem} fs] && ($fs eq "xft"))} {
    if {[package vsatisfies [package provide Tcl] 8.7-]} {
    addSample $w Emoji "😀💩👍🇳🇱"
	addSample $w Emoji "😀💩👍🇳🇱"
    } else {
	addSample $w Emoji \
		"\uD83D\uDE00\uD83D\uDCA9\uD83D\uDC4D\uD83C\uDDF3\uD83C\uDDF1"
    }
}

## We're done processing, so change things back to normal running...
destroy $w.wait
$w conf -cursor $oldCursor
Changes to library/demos/widget.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16

17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15

16
17
18
19
20
21
22
23












-
+


-
+







#!/bin/sh
# the next line restarts using wish \
exec wish "$0" ${1+"$@"}

# widget --
# This script demonstrates the various widgets provided by Tk, along with many
# of the features of the Tk toolkit. This file only contains code to generate
# 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 Tk	8.5-
package require msgcat

eval destroy [winfo child .]
destroy {*}[winfo children .]
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"} {
    # This won't work everywhere, but there's no other way in core Tk at the
    # moment to display a coloured icon.
338
339
340
341
342
343
344

345
346
347
348
349
350
351
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352







+







    @@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 ttkspin	Themed 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)
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635







-
+







    } 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
    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 --
719
720
721
722
723
724
725
726
727
728
729




730
731
732
733
734
720
721
722
723
724
725
726




727
728
729
730
731
732
733
734
735







-
-
-
-
+
+
+
+





# 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}]"
"[mc "Copyright \xA9 %s" {1996-1997 Sun Microsystems, Inc.}]
[mc "Copyright \xA9 %s" {1997-2000 Ajuba Solutions, Inc.}]
[mc "Copyright \xA9 %s" {2001-2009 Donal K. Fellows}]
[mc "Copyright \xA9 %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
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.
# 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:
Changes to library/entry.tcl.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
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.
# 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:
207
208
209
210
211
212
213

214
215
216
217
218
219
220
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221







+







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}
    bind Entry <Mod4-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.
289
290
291
292
293
294
295

296
297


298
299
300
301
302




303
304













305
306
307
308
309
310
311
290
291
292
293
294
295
296
297


298
299
300




301
302
303
304
305

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325







+
-
-
+
+

-
-
-
-
+
+
+
+

-
+
+
+
+
+
+
+
+
+
+
+
+
+







}
bind Entry <<TkAccentBackspace>> {
    tk::EntryBackspace %W
}

# A few additional bindings of my own.

if {[tk windowingsystem] ne "aqua"} {
bind Entry <Button-2> {
    if {!$tk_strictMotif} {
    bind Entry <Button-2> {
        if {!$tk_strictMotif} {
        ::tk::EntryScanMark %W %x
    }
}
bind Entry <B2-Motion> {
    if {!$tk_strictMotif} {
        }
    }
    bind Entry <B2-Motion> {
        if {!$tk_strictMotif} {
        ::tk::EntryScanDrag %W %x
     }
        }
    }
} else {
    bind Entry <Button-3> {
        if {!$tk_strictMotif} {
        ::tk::EntryScanMark %W %x
        }
    }
    bind Entry <B3-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.
#
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
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







+
+
+
+











+
+
+
+


















+
+
+
+







#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

if {[tk windowingsystem] eq "win32"}  {
    proc ::tk::EntryNextWord {w start} {
        # the check on [winfo class] is because the spinbox also uses this proc
        if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	    return end
	}
	set pos [tcl_endOfWord [$w get] [$w index $start]]
	if {$pos >= 0} {
	    set pos [tcl_startOfNextWord [$w get] $pos]
	}
	if {$pos < 0} {
	    return end
	}
	return $pos
    }
} else {
    proc ::tk::EntryNextWord {w start} {
        # the check on [winfo class] is because the spinbox also uses this proc
        if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	    return end
	}
	set pos [tcl_endOfWord [$w get] [$w index $start]]
	if {$pos < 0} {
	    return end
	}
	return $pos
    }
}

# ::tk::EntryPreviousWord --
#
# Returns the index of the previous word position before a given
# position in the entry.
#
# Arguments:
# w -		The entry window in which the cursor is to move.
# start -	Position at which to start search.

proc ::tk::EntryPreviousWord {w start} {
    # the check on [winfo class] is because the spinbox also uses this proc
    if {[winfo class $w] eq "Entry" && [$w cget -show] ne ""} {
	return 0
    }
    set pos [tcl_startOfPreviousWord [$w get] [$w index $start]]
    if {$pos < 0} {
	return 0
    }
    return $pos
}

Changes to library/focus.tcl.
1
2
3
4
5
6

7
8
9
10
11
12
13
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.
# 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
Changes to library/fontchooser.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
8
9
10
11
12
13
14

15
16




17
18
19
20
21

22
23
24
25

26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56





57
58
59
60
61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92

93
94
95
96
97
98
99
100
101







-
+

-
-
-
-
+
+
+
+

-




-

-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





-
+
-
-
-
-
-







-
-
+
+











+
+
+




+
+
+
+
-
-
+
+
+

+
-
+
+







# 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(fonts) [lsort -dictionary -unique [font families]]
    set S(styles) [list \
	[::msgcat::mc "Regular"] \
	[::msgcat::mc "Italic"] \
	[::msgcat::mc "Bold"] \
	[::msgcat::mc "Bold Italic"] \
            [::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(-title) {}
    set S(-command) ""
    set S(-font) TkDefaultFont
    set S(bad) [list ]
}

proc ::tk::fontchooser::Canonical {} {
    variable S

    foreach style $S(styles) {
        lappend S(styles,lcase) [string tolower $style]
    }
    set S(sizes,lcase) $S(sizes)
    set S(sampletext) [::msgcat::mc "AaBbYyZz01"]

    # 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]
    }
}

proc ::tk::fontchooser::Setup {} {
    variable S

    # Canonical versions of font families, styles, etc. for easier searching
    Canonical
    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]]
            [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

    Canonical

    if {![winfo exists $S(W)]} {
        Create
        wm transient $S(W) [winfo toplevel $S(-parent)]
        tk::PlaceWindow $S(W) widget $S(-parent)
        if {[string trim $S(-title)] eq ""} {
            wm title $S(W) [::msgcat::mc "Font"]
        } else {
            wm title $S(W) $S(-title)
    }
    set S(fonts) [lsort -dictionary [font families]]
        }
    }
    set S(fonts) [lsort -dictionary -unique [font families]]
    set S(fonts,lcase) {}
    foreach font $S(fonts) {
    foreach font $S(fonts) { lappend S(fonts,lcase) [string tolower $font]}
        lappend S(fonts,lcase) [string tolower $font]
    }
    wm deiconify $S(W)
}

proc ::tk::fontchooser::Hide {} {
    variable S
    wm withdraw $S(W)
}
87
88
89
90
91
92
93
94

95
96
97

98
99
100
101
102
103
104
105
106
107
108
109


110
111
112
113
114


115
116

117
118
119
120
121
122
123
124
125
126














127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143



144
145
146
147
148
149
150
151
152
153
154
155
156

157
158

159
160

161
162
163
164


165
166
167


168
169
170


171
172
173
174
175
176
177



178
179
180
181



182
183
184
185

186
187

188
189

190
191
192
193
194
195
196
197
198
199

200
201

202
203

204
205



206
207
208
209
210
211
212
111
112
113
114
115
116
117

118
119
120

121
122
123
124
125
126
127
128
129
130
131


132
133
134

135


136
137
138

139
140
141
142
143






144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190

191
192

193
194
195


196
197
198


199
200
201


202
203
204
205
206
207



208
209
210
211



212
213
214
215
216
217

218
219

220
221

222
223
224
225
226
227
228
229
230
231

232
233

234
235

236
237

238
239
240
241
242
243
244
245
246
247







-
+


-
+










-
-
+
+

-

-
-
+
+

-
+




-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
















-
+
+
+












-
+

-
+

-
+


-
-
+
+

-
-
+
+

-
-
+
+




-
-
-
+
+
+

-
-
-
+
+
+



-
+

-
+

-
+









-
+

-
+

-
+

-
+
+
+







    }

    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}]
                    [expr {[info exists S($name)] ? $S($name) : $default}]
        }
        lappend result -visible \
            [expr {[winfo exists $S(W)] && [winfo ismapped $S(W)]}]
                [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"
                "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]
            -font $S(-font) -command $S(-command)]
    set r [tclParseConfigSpec [namespace which -variable S] $specs DONTSETDEFAULTS $args]
    if {![winfo exists $S(-parent)]} {
	set code [list TK LOOKUP WINDOW $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>>

    if {[winfo exists $S(W)]} {
        if {{-font} in $args} {
            Init $S(-font)
            event generate $S(-parent) <<TkFontchooserFontChanged>>
        }

        if {[string trim $S(-title)] eq {}} {
            wm title $S(W) [::msgcat::mc Font]
        } else {
            wm title $S(W) $S(-title)
        }
        $S(W).ok configure -state $S(nstate)
        $S(W).apply configure -state $S(nstate)
    }
    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)}
        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)
                -textvariable [namespace which -variable S](font)
        ttk::entry $S(W).estyle -width 10 \
            -textvariable [namespace which -variable S](style)
                -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}
                -width 3 -validate key -validatecommand {regexp -- {^-*[0-9]*$} %P}

        ttk_slistbox $S(W).lfonts -height 7 -exportselection 0 \
            -selectmode browse -activestyle none \
            -listvariable [namespace which -variable S](fonts)
                -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)
                -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)
                -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]]
                -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]]
                -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]]
                -command [namespace code [list Done 1]]
        ::ttk::button $S(W).cancel -text [::msgcat::mc Cancel] \
            -command [namespace code [list Done 0]]
                -command [namespace code [list Done 0]]
        ::tk::AmpWidget ::ttk::button $S(W).apply -text [::msgcat::mc "&Apply"] \
            -command [namespace code [list 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}]
                [expr {[font measure TkDefaultFont "Helvetica"] + $scroll_width}]
        set minsize(styles) \
            [expr {[font measure TkDefaultFont "Bold Italic"] + $scroll_width}]
                [expr {[font measure TkDefaultFont "Bold Italic"] + $scroll_width}]
        set minsize(sizes) \
            [expr {[font measure TkDefaultFont "-99"] + $scroll_width}]
                [expr {[font measure TkDefaultFont "-99"] + $scroll_width}]
        set min [expr {$minsize(gap) * 4}]
        foreach {what width} [array get minsize] {incr min $width}
        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]]
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

265
266

267
268
269
270








271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291





292

293
294




295
296
297
298
299
300
301
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270


271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

298
299

300
301



302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326



327
328
329
330
331
332
333


334
335
336
337
338
339
340
341
342
343
344







-
+








-
-
+
-











+














-
+

-
+

-
-
-
+
+
+
+
+
+
+
+
-

















-
-
-
+
+
+
+
+

+
-
-
+
+
+
+







        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)
                -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 $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 rowconfigure $outer 2 -weight 1
        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]]
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](style) \
            write [namespace code [list Tracer]]
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](font) \
            write [namespace code [list Tracer]]
    } else {
        Init $S(-font)
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](strike) \
                write [namespace code [list Tracer]]
        trace add variable [namespace which -variable S](under) \
                write [namespace code [list Tracer]]
    }

    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]]
    trace remove variable S(size) write [namespace code [list Tracer]]
    trace remove variable S(style) write [namespace code [list Tracer]]
    trace remove variable S(font) write [namespace code [list Tracer]]
    trace remove variable S(strike) write [namespace code [list Tracer]]
    trace remove variable S(under) write [namespace code [list Tracer]]
    destroy $S(W)
    if {$ok} {
    if {$ok && $S(-command) ne ""} {
        uplevel #0 $S(-command) [list $S(result)]
        if {$S(-command) ne ""} {
            uplevel #0 $S(-command) [list $S(result)]
        }
        event generate $S(-parent) <<TkFontchooserFontChanged>>
    }
}

# ::tk::fontchooser::Apply --
#
#	Call the -command procedure appending the current font
#	Errors are reported via the background error mechanism
317
318
319
320
321
322
323

324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379


380
381

382
383
384
385
386




387
388
389
390
391








392
393
394
395
396
397
398
399
400












401


402
403






404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
















420

421
422
423
424
425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384

385
386



387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404

405
406
407
408
409
410
411
412
413
414
415


416
417


418





419
420
421
422
423




424
425
426
427
428
429
430
431









432
433
434
435
436
437
438
439
440
441
442
443
444
445
446


447
448
449
450
451
452
453
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







+






+



-







-


-
-
-











-







-











-
-
+
+
-
-
+
-
-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

+
+
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+













-
+







# Arguments:
#       defaultFont     font to use as the default
#
proc ::tk::fontchooser::Init {{defaultFont ""}} {
    variable S

    if {$S(first) || $defaultFont ne ""} {
        Canonical
        if {$defaultFont eq ""} {
            set defaultFont [[entry .___e] cget -font]
            destroy .___e
        }
        array set F [font actual $defaultFont]
        set S(font) $F(-family)
        set S(style) [::msgcat::mc "Regular"]
        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
    # We don't need to process strike and under
    if {$var2 ni [list strike under]} {
    set nstate normal
    # Make selection in each listbox
        # Make selection in 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
        set value [string tolower $S($var2)]
        $S(W).l${var2}s selection clear 0 end
        set n [lsearch -exact $S(${var2}s,lcase) $value]
        $S(W).l${var2}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
            set S($var2) [lindex $S(${var2}s) $n]
            $S(W).e$var2 icursor end
            $S(W).e$var2 selection clear
            if {[set i [lsearch $S(bad) $var2]] >= 0} {
                set S(bad) [lreplace $S(bad) $i $i]
            }
        } 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
            set n [lsearch -glob $S(${var2}s,lcase) "$value*"]
            if {$var2 ne "size" || !([regexp -- {^(-[0-9]+|[0-9]+)$} $value] && $value >= -4096 && $value <= 4096)} {
                 if {[lsearch $S(bad) $var2] < 0} {
                     lappend S(bad) $var2
                 }
            } else {
                if {[set i [lsearch $S(bad) $var2]] >= 0} {
                    set S(bad) [lreplace $S(bad) $i $i]
                }
            }
        }
        $S(W).l${var2}s see $n
    }
    if {[llength $S(bad)] == 0} {
        set S(nstate) normal
    if {!$bad} {Update}
    $S(W).ok configure -state $nstate
        Update
    } else {
        set S(nstate) disabled
    }
    $S(W).ok configure -state $S(nstate)
    $S(W).apply configure -state $S(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}

    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)
    set S(-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 --
# ::tk::fontchooser::ttk_slistbox --
#
#	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 {
Changes to library/iconlist.tcl.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
1
2
3
4
5


6
7
8
9
10
11
12
13
14





-
-
+
+







# 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
# Copyright (c) 1994-1998 Sun Microsystems, Inc.
# Copyright (c) 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>
334
335
336
337
338
339
340
341
342


343
344
345
346
347
348
349
334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349







-
-
+
+







	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 $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
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387







-
+







	}

	my DrawSelection
    }

    method DrawSelection {} {
	$canvas delete selection
	$canvas itemconfigure selectionText -fill black
	$canvas itemconfigure selectionText -fill $fill
	$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
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451











452
453
454
455
456
457
458
459
460



461
462
463
464
465
466
467
418
419
420
421
422
423
424



425



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462


463
464
465
466
467
468
469
470
471
472







-
-
-
+
-
-
-


















+
-
-
-
+
+
+
+
+
+
+
+
+
+
+







-
-
+
+
+







	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
	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}]

	if {[tk windowingsystem] eq "aqua"} {
	bind $canvas <Shift-MouseWheel>	[namespace code {my MouseWheel %D}]
	bind $canvas <Option-Shift-MouseWheel>	[namespace code {my MouseWheel %D -12}]

	    bind $canvas <Shift-MouseWheel>	[namespace code {my MouseWheel [expr {40 * (%D)}]}]
	    bind $canvas <Option-Shift-MouseWheel>	[namespace code {my MouseWheel [expr {400 * (%D)}]}]
	    bind $canvas <Command-Key> 	{# nothing}
	    bind $canvas <Mod4-Key>	{# nothing}
	} else {
	    bind $canvas <Shift-MouseWheel>	[namespace code {my MouseWheel %D}]
	}
	if {[tk windowingsystem] eq "x11"} {
	    bind $canvas <Shift-Button-4>	[namespace code {my MouseWheel 120}]
	    bind $canvas <Shift-Button-5>	[namespace code {my MouseWheel -120}]
	}

	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 <Alt-Key>		{# nothing}
	bind $canvas <Meta-Key> 	{# nothing}
	bind $canvas <Control-Key> 	{# nothing}

	bind $canvas <FocusIn>		[namespace code {my FocusIn}]
	bind $canvas <FocusOut>		[namespace code {my FocusOut}]

	return $w
    }

492
493
494
495
496
497
498
499

500
501
502



503


504
505
506
507
508
509
510
497
498
499
500
501
502
503

504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519







-
+



+
+
+
-
+
+







	my Motion1 $x $y
	set ::tk::Priv(afterId) [after 50 [namespace code {my AutoScan}]]
    }

    # ----------------------------------------------------------------------

    # Event handlers
    method MouseWheel {amount {factor -120.0}} {
    method MouseWheel {amount} {
	if {$noScroll || $::tk_strictMotif} {
	    return
	}
	if {$amount > 0} {
	    $canvas xview scroll [expr {(-119-$amount) / 120}] units
	} else {
	$canvas xview scroll [expr {$amount/$factor}] units
	    $canvas xview scroll [expr {-($amount / 120)}] units
	}
    }
    method Btn1 {x y} {
	focus $canvas
	set i [$w index @$x,$y]
	if {$i eq ""} {
	    return
	}
Changes to library/icons.tcl.
1
2
3
4
5
6
7

8
9
10
11

12
13
14
15
16
17
18
1
2
3
4
5
6

7
8
9
10

11
12
13
14
15
16
17
18






-
+



-
+







# 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/)
#	(https://creativecommons.org/licenses/by-sa/3.0/)
#
#	See http://tango.freedesktop.org/Tango_Desktop_Project
#
# Copyright © 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
# Copyright (c) 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
Changes to library/images/logo.eps.
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
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
%%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
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
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
%%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
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
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
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
%%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
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
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
%%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
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
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
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







# 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.
# 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:
#
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60

61
62
63
64
65
66
67
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59

60
61
62
63
64
65
66
67







-
+









-
+












-
+


-
+








# 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> {
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-Button-1> {
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-Button-1> {
bind Listbox <Shift-1> {
    tk::ListboxBeginExtend %W [%W index @%x,%y]
}
bind Listbox <Control-Button-1> {
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
}
165
166
167
168
169
170
171
172

173
174
175
176
177
178





179
180
181
182
183
184
185
186
187
188
189






















































190
191
192
193
194
195
196
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183











184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244







-
+






+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	%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> {
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> {
    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
    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> {
	if {%D >= 0} {
	    %W yview scroll [expr {-%D/30}] units
	} else {
	    %W yview scroll [expr {(29-%D)/30}] units
	}
    }
    bind Listbox <Shift-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {-%D/30}] units
	} else {
	    %W xview scroll [expr {(29-%D)/30}] units
	}
    }
}

if {[tk windowingsystem] eq "x11"} {
    # 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:
    #	https://linuxreviews.org/HOWTO_change_the_mouse_speed_in_X
    bind Listbox <4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -5 units
	}
    }
    bind Listbox <Shift-4> {
	if {!$tk_strictMotif} {
	    %W xview scroll -5 units
	}
    }
    bind Listbox <5> {
	if {!$tk_strictMotif} {
	    %W yview scroll 5 units
	}
    }
    bind Listbox <Shift-5> {
	if {!$tk_strictMotif} {
	    %W xview 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;
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306







-
+







	    $w selection clear 0 end
	    $w selection set $el
	    set Priv(listboxPrev) $el
	    tk::FireListboxSelectEvent $w
	}
	extended {
	    set i $Priv(listboxPrev)
	    if {$i eq ""} {
	    if {$i < 0} {
		set i $el
		$w selection set $el
	    }
	    if {[$w selection includes anchor]} {
		$w selection clear $i $el
		$w selection set anchor $el
	    } else {
Changes to library/megawidget.tcl.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







# 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
# Copyright (c) 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

Changes to library/menu.tcl.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
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>
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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:
265
266
267
268
269
270
271
272
273


274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
265
266
267
268
269
270
271


272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295







-
-
+
+














-
+







	    "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
	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]} {
    if {[catch {PostMenubuttonMenu $w $menu $x $y} msg opt]} {
	# Error posting menu (e.g. bogus -postcommand). Unpost it and
	# reflect the error.
	MenuUnpost {}
	return -options $opt $msg
    }

    set Priv(tearoff) $tearoff
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353







-
+








    catch {
	if {$mb ne ""} {
	    set menu [$mb cget -menu]
	    $menu unpost
	    set Priv(postedMb) {}
	    if {$::tk_strictMotif} {
	        $mb configure -cursor $Priv(cursor)
		$mb configure -cursor $Priv(cursor)
	    }
	    if {[tk windowingsystem] ne "aqua"} {
		$mb configure -relief $Priv(relief)
	    } else {
		$mb configure -state normal
	    }
	} elseif {$Priv(popup) ne ""} {
471
472
473
474
475
476
477
478

479
480
481
482
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
471
472
473
474
475
476
477

478
479
480
481
482
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







-
+









-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







# x -			The x position of the mouse.
# y -			The y position of the mouse.
# state -		Modifier state (tells whether buttons are down).

proc ::tk::MenuMotion {menu x y state} {
    variable ::tk::Priv
    if {$menu eq $Priv(window)} {
        set activeindex [$menu index active]
	set activeindex [$menu index active]
	if {[$menu cget -type] eq "menubar"} {
	    if {[info exists Priv(focus)] && $menu ne $Priv(focus)} {
		$menu activate @$x,$y
		GenerateMenuSelect $menu
	    }
	} else {
	    $menu activate @$x,$y
	    GenerateMenuSelect $menu
	}
        set index [$menu index @$x,$y]
        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}"]
                }
            }
        }
	set index [$menu index @$x,$y]
	if {[info exists Priv(menuActivated)] \
		&& $index ne "none" \
		&& $index >= 0 \
		&& $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 [list catch [list \
			    $menu postcascade active]]]
		} else {
		    set Priv(menuDeactivatedTimer) \
			[after $delay [list catch [list
			    $menu postcascade none]]]
		}
	    }
	}
    }
}

# ::tk::MenuButtonDown --
# Handles button presses in menus.  There are a couple of tricky things
# here:
# 1. Change the posted cascade entry (if any) to match the mouse position.
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
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







-
+

-
-
-
-
-
+
+
+
+
+
+




















-
+







# Arguments:
# menu -		The menu window.

proc ::tk::MenuButtonDown menu {
    variable ::tk::Priv

    if {![winfo viewable $menu]} {
        return
	return
    }
    if {[$menu index active] eq "none"} {
        if {[$menu cget -type] ne "menubar" } {
            set Priv(window) {}
        }
        return
    set activeindex [$menu index active]
    if {($activeindex eq "none") || ($activeindex < 0)} {
	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" \
		&& [winfo class [winfo parent $menu]] eq "Menu" \
		&& [winfo ismapped [winfo parent $menu]]} {
	    set menu [winfo parent $menu]
	}

	if {$Priv(menuBar) eq {}} {
	    set Priv(menuBar) $menu
	    if {$::tk_strictMotif} {
		set Priv(cursor) [$menu cget -cursor]
		$menu configure -cursor arrow
	    }
	    if {[$menu type active] eq "cascade"} {
		set Priv(menuActivated) 1
	    }
        }
	}

	# Don't update grab information if the grab window isn't changing.
	# Otherwise, we'll get an error when we unpost the menus and
	# restore the grab, since the old grab window will not be viewable
	# anymore.

	if {$menu ne [grab current $menu]} {
581
582
583
584
585
586
587
588


589
590
591
592
593
594
595
585
586
587
588
589
590
591

592
593
594
595
596
597
598
599
600







-
+
+







# menu -		The menu window.
# rootx, rooty -	Root coordinates of mouse.
# state -		Modifier state.

proc ::tk::MenuLeave {menu rootx rooty state} {
    variable ::tk::Priv
    set Priv(window) {}
    if {[$menu index active] eq "none"} {
    set activeindex [$menu index active]
    if {($activeindex eq "none") || ($activeindex < 0)} {
	return
    }
    if {[$menu type active] eq "cascade" \
	    && [winfo containing $rootx $rooty] eq \
		[$menu entrycget active -menu]} {
	return
    }
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
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







-
-
+
+

















-
+


-
-
+
+







	set menu [$w entrycget active -menu]
	MenuFirstEntry $menu
    } elseif {[$w type active] eq "tearoff"} {
	::tk::TearOffMenu $w
	MenuUnpost $w
    } elseif {[$w cget -type] eq "menubar"} {
	$w postcascade none
	set active [$w index active]
	set isCascade [string equal [$w type $active] "cascade"]
	set activeindex [$w index active]
	set isCascade [string equal [$w type $activeindex] "cascade"]

	# Only de-activate the active item if it's a cascade; this prevents
	# the annoying "activation flicker" you otherwise get with
	# checkbuttons/commands/etc. on menubars

	if { $isCascade } {
	    $w activate none
	    event generate $w <<MenuSelect>>
	}

	MenuUnpost $w

	# If the active item is not a cascade, invoke it.  This enables
	# the use of checkbuttons/commands/etc. on menubars (which is legal,
	# but not recommended)

	if { !$isCascade } {
	    uplevel #0 [list $w invoke $active]
	    uplevel #0 [list $w invoke $activeindex]
	}
    } else {
	set active [$w index active]
	if {$Priv(popup) eq "" || $active ne "none"} {
	set activeindex [$w index active]
	if {($Priv(popup) eq "") || (($activeindex ne "none") && ($activeindex >= 0))} {
	    MenuUnpost $w
	}
	uplevel #0 [list $w invoke active]
    }
}

# ::tk::MenuEscape --
793
794
795
796
797
798
799
800


801
802
803
804
805
806
807
798
799
800
801
802
803
804

805
806
807
808
809
810
811
812
813







-
+
+







	while {$i >= $length} {
	    incr i -$length
	}
	set mb [lindex $buttons $i]
	if {[winfo class $mb] eq "Menubutton" \
		&& [$mb cget -state] ne "disabled" \
		&& [$mb cget -menu] ne "" \
		&& [[$mb cget -menu] index last] ne "none"} {
		&& [[$mb cget -menu] index last] ne "none" \
		&& [[$mb cget -menu] index last] >= 0} {
	    break
	}
	if {$mb eq $w} {
	    return
	}
	incr i $count
    }
815
816
817
818
819
820
821
822


823
824
825

826
827
828


829
830
831

832
833
834
835
836
837
838
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







-
+
+


-
+

-
-
+
+


-
+







#
# Arguments:
# menu -			Menu window that received the keystroke.
# count -			1 means go to the next lower entry,
#				-1 means go to the next higher entry.

proc ::tk::MenuNextEntry {menu count} {
    if {[$menu index last] eq "none"} {
    set last [$menu index last]
    if {($last eq "none") || ($last < 0)} {
	return
    }
    set length [expr {[$menu index last]+1}]
    set length [expr {$last+1}]
    set quitAfter $length
    set active [$menu index active]
    if {$active eq "none"} {
    set activeindex [$menu index active]
    if {($activeindex eq "none") || ($activeindex < 0)} {
	set i 0
    } else {
	set i [expr {$active + $count}]
	set i [expr {$activeindex + $count}]
    }
    while {1} {
	if {$quitAfter <= 0} {
	    # We've tried every entry in the menu.  Either there are
	    # none, or they're all disabled.  Just give up.

	    return
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
853
854
855
856
857
858
859

860
861
862
863
864
865
866
867







-
+







	if {[catch {$menu entrycget $i -state} state] == 0} {
	    if {$state ne "disabled" && \
		    ($i!=0 || [$menu cget -type] ne "tearoff" \
		    || [$menu type 0] ne "tearoff")} {
		break
	    }
	}
	if {$i == $active} {
	if {$i == $activeindex} {
	    return
	}
	incr i $count
	incr quitAfter -1
    }
    $menu activate $i
    GenerateMenuSelect $menu
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
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







-
+









-
+


-
-
-
+
+
+
-









-
+








proc ::tk::MenuFind {w char} {
    set char [string tolower $char]
    set windowlist [winfo child $w]

    foreach child $windowlist {
	# Don't descend into other toplevels.
        if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	    continue
	}
	if {[winfo class $child] eq "Menu" && \
		[$child cget -type] eq "menubar"} {
	    if {$char eq ""} {
		return $child
	    }
	    set last [$child index last]
	    for {set i [$child cget -tearoff]} {$i <= $last} {incr i} {
		if {[$child type $i] eq "separator"} {
		if {([$child type $i] eq "separator") || ([$child entrycget $i -state] eq "disabled")} {
		    continue
		}
		set char2 [string index [$child entrycget $i -label] \
			[$child entrycget $i -underline]]
		if {$char eq [string tolower $char2] || $char eq ""} {
		set underline [$child entrycget $i -underline]
		if {$underline >= 0} {
		    if {$char eq [string tolower [string index [$child entrycget $i -label] $underline]]} {
		    if {[$child entrycget $i -state] ne "disabled"} {
			return $child
		    }
		}
	    }
	}
    }

    foreach child $windowlist {
	# Don't descend into other toplevels.
        if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	if {[winfo toplevel $w] ne [winfo toplevel $child]} {
	    continue
	}
	switch -- [winfo class $child] {
	    Menubutton {
		set char2 [string index [$child cget -text] \
			[$child cget -underline]]
		if {$char eq [string tolower $char2] || $char eq ""} {
1064
1065
1066
1067
1068
1069
1070
1071


1072
1073
1074
1075
1076
1077
1078
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
1084
1085







-
+
+







# menu -		Name of the menu window (possibly empty).

proc ::tk::MenuFirstEntry menu {
    if {$menu eq ""} {
	return
    }
    tk_menuSetFocus $menu
    if {[$menu index active] ne "none"} {
    set activeindex [$menu index active]
    if {($activeindex ne "none") && ($activeindex >= 0)} {
	return
    }
    set last [$menu index last]
    if {$last eq "none"} {
	return
    }
    for {set i 0} {$i <= $last} {incr i} {
1111
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
1132







-
+







    set i ""
    if {![regexp {^active$|^last$|^none$|^[0-9]|^@} $s]} {
	catch {set i [$menu index $s]}
	return $i
    }
    set last [$menu index last]
    if {$last eq "none"} {
	return
	return ""
    }
    for {set i 0} {$i <= $last} {incr i} {
	if {![catch {$menu entrycget $i -label} label]} {
	    if {$label eq $s} {
		return $i
	    }
	}
1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1141
1142
1143
1144
1145
1146
1147

1148
1149
1150
1151
1152
1153
1154
1155







-
+







# 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} {
    proc ::tk::PostMenubuttonMenu {button menu cx cy} {
	set entry ""
	if {[$button cget -indicatoron]} {
	    set entry [MenuFindName $menu [$button cget -text]]
	    if {$entry eq ""} {
		set entry 0
	    }
	}
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
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







-
+






-
+















-
+














-
-
-
-





-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







	    }
	    left {
		incr x [expr {-[winfo reqwidth $menu]}]
	    }
	    right {
		incr x [winfo width $button]
	    }
	    default {
	    default {  # flush
		incr x [expr {[winfo width $button] - [winfo reqwidth $menu] - 5}]
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
} else {
    proc ::tk::PostMenubuttonMenu {button menu} {
    proc ::tk::PostMenubuttonMenu {button menu cx cy} {
	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]}]
			   + [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]
		}
	    default {  # flush
                if {[$button cget -indicatoron]} {
                    if {$cx ne ""} {
                        set x [expr {$cx - [winfo reqwidth $menu] / 2}]
                        set l [font metrics [$menu cget -font] -linespace]
                        set y [expr {$cy - $l/2 - 2}]
                    } else {
                        incr x [expr {([winfo width $button] - \
				[winfo reqwidth $menu])/ 2}]
                    }
                } else {
                    incr y [winfo height $button]
                }
	    }
	}
	PostOverPoint $menu $x $y $entry
    }
}

# ::tk::PostOverPoint --
1238
1239
1240
1241
1242
1243
1244

1245

1246
1247
1248
1249
1250
1251
1252
1247
1248
1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259
1260
1261
1262







+
-
+







#			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 type $entry] ni {separator tearoff} &&
	    if {[$menu entrycget $entry -state] ne "disabled"} {
		[$menu entrycget $entry -state] ne "disabled"} {
		$menu activate $entry
		GenerateMenuSelect $menu
	    }
	} else {
	    $menu post $x $y
	}
	return
1336
1337
1338
1339
1340
1341
1342
1343
1344


1345
1346
1347
1348
1349
1350




1351
1352
1353
1354
1355
1356
1357
1346
1347
1348
1349
1350
1351
1352


1353
1354






1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365







-
-
+
+
-
-
-
-
-
-
+
+
+
+







    }
    focus $menu
}

proc ::tk::GenerateMenuSelect {menu} {
    variable ::tk::Priv

    if {$Priv(activeMenu) eq $menu \
	    && $Priv(activeItem) eq [$menu index active]} {
    if {$Priv(activeMenu) ne $menu \
	    || $Priv(activeItem) ne [$menu index active]} {
	return
    }

    set Priv(activeMenu) $menu
    set Priv(activeItem) [$menu index active]
    event generate $menu <<MenuSelect>>
	set Priv(activeMenu) $menu
	set Priv(activeItem) [$menu index active]
	event generate $menu <<MenuSelect>>
    }
}

# ::tk_popup --
# This procedure pops up a menu and sets things up for traversing
# the menu and its submenus.
#
# Arguments:
1365
1366
1367
1368
1369
1370
1371
1372

1373
1374
1375
1376
1377
1378
1379
1373
1374
1375
1376
1377
1378
1379

1380
1381
1382
1383
1384
1385
1386
1387







-
+







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
	tk::SaveGrabInfo $menu
	grab -global $menu
	set Priv(popup) $menu
	set Priv(window) $menu
	set Priv(menuActivated) 1
	tk_menuSetFocus $menu
    }
}
Changes to library/msgbox.tcl.
1
2
3
4
5
6

7
8
9
10
11
12
13
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.
# 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
#
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
1

2
3

4
5
6





7
8
9
10
11
12
13
14
15


16
17
18
19



20
21
22
23
24
25


26
27
28



29
30
31
32
33
34
35


36
37
38
39
40

41
42
43
44
45
46







47
48
49
50
51
52
53
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 "&Abort" "&P\u0159eru\u0161it"
    ::msgcat::mcset cs "&About..." "&O programu..."
    ::msgcat::mcset cs "All Files" "Všechny soubory"
    ::msgcat::mcset cs "All Files" "V\u0161echny 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 "&Blue" "&Modr\341"
    ::msgcat::mcset cs "Cancel" "Zru\u0161it"
    ::msgcat::mcset cs "&Cancel" "&Zru\u0161it"
    ::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 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 "&Copy" "&Kop\355rovat"
    ::msgcat::mcset cs "Cu&t" "V&y\u0159\355znout"
    ::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 "Directory \"%1\$s\" does not exist." "Adres\341\u0159 \"%1\$s\" neexistuje."
    ::msgcat::mcset cs "&Directory:" "&Adres\341\u0159:"
    ::msgcat::mcset cs "&Edit" "&\332pravy"
    ::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\" already exists.\nDo you want to overwrite it?" "Soubor \"%1\$s\" ji\u017e existuje.\nChcete jej p\u0159epsat?"
    ::msgcat::mcset cs "File \"%1\$s\" already exists.\n\n" "Soubor \"%1\$s\" ji\u017e 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 "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 "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 "&Green" "Ze&len\341"
    ::msgcat::mcset cs "&Help" "&N\341pov\u011bda"
    ::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 "Invalid file name \"%1\$s\"." "\u0160patn\351 jm\351no 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 "Open" "Otev\u0159\355t"
    ::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 "&Quit" "&Ukon\u010dit"
    ::msgcat::mcset cs "&Red" "\u010ce&rven\341"
    ::msgcat::mcset cs "Replace existing file?" "Nahradit st\341vaj\355c\355 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 "&Save" "&Ulo\u017eit"
    ::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 naháí"
    ::msgcat::mcset cs "&Selection:" "&ýběr:"
    ::msgcat::mcset cs "Skip Messages" "Přeskočit zpávy"
    ::msgcat::mcset cs "Select a file to source" "Vybrat soubor k nahr\341n\355"
    ::msgcat::mcset cs "&Selection:" "&V\375b\u011br:"
    ::msgcat::mcset cs "Skip Messages" "P\u0159esko\u010dit zpr\341vy"
    ::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 "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" "červeá"
    ::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
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å"
    ::msgcat::mcset da "&Blue" "&Bl\u00E5"
    ::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 "Choose Directory" "V\u00E6lg 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"
27
28
29
30
31
32
33
34
35


36
37
38
39
40
41
42
43
44
45
46
47
48




49
50

51
52
53
54
55
56
57


58
59
60
61
62

63
64
65
66
67
68

69
70
71
72

73
74
75

76
77
78
27
28
29
30
31
32
33


34
35
36
37
38
39
40
41
42
43
44




45
46
47
48
49

50
51
52
53
54
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 "&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" "Å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 "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ød"
    ::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ælg logfil"
    ::msgcat::mcset da "Select a file to source" "Vælg kørbar fil"
    ::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ør..."
    ::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å"
    ::msgcat::mcset da "blue" "bl\u00E5"
    ::msgcat::mcset da "cancel" "afbryd"
    ::msgcat::mcset da "extension"
    ::msgcat::mcset da "extensions"
    ::msgcat::mcset da "green" "grøn"
    ::msgcat::mcset da "green" "gr\u00F8n"
    ::msgcat::mcset da "ignore" "ignorer"
    ::msgcat::mcset da "ok"
    ::msgcat::mcset da "red" "rød"
    ::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
1
2

3
4
5
6
7
8
9
10
11
12



13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45

46
47
48
49
50
51
52




53
54
55
56
57
58
59
60
61
62
63
64
65


66
67
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 "&About..." "&\u00dcber..."
    ::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 "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öschen"
    ::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 "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.\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 "Font" "Schriftart"
    ::msgcat::mcset de "&Font:" "Schriftart:"
    ::msgcat::mcset de "Font st&yle:" "Schriftschnitt:"
    ::msgcat::mcset de "&Green" "&Grün"
    ::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ültiger Dateiname \"%1\$s\"."
    ::msgcat::mcset de "Invalid file name \"%1\$s\"." "Ung\u00fcltiger 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 "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 "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 "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 "&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 "Skip Messages" "Weitere Nachrichten \u00fcberspringen"
    ::msgcat::mcset de "&Source..." "&Ausf\u00fchren..."
    ::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 "Tcl for Windows" "Tcl f\u00fcr 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 "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
1
2
3
4
5






6
7
8
9
10
11
12
13









14
15
16
17
18
19
20
21
22
23




24
25
26
27
28
29

30
31

32
33











34
35
36
37
38
39
40
41
42
43
44
45








46
47
48
49
50
51
52
53
54




55
56
57
58
59






60
61
62
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 "&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." \
"Δεν είναι δυνατή η αλλαγή καταλόγου σε \"%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 >>"         "Λεπτομέρειες >>"
"\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." \
                                        "Ο κατάλογος \"%1\$s\" δεν υπάρχει."
    ::msgcat::mcset el "&Directory:"         "&Κατάλογος:"
    ::msgcat::mcset el "Error: %1\$s"       "Λάθος: %1\$s"
    ::msgcat::mcset el "Exit"               "Έξοδος"
                                        "\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?" \
               "Το αρχείο \"%1\$s\" ήδη υπάρχει.\nΘέλετε να επικαλυφθεί;"
               "\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" \
                   "Το αρχείο \"%1\$s\" ήδη υπάρχει.\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." \
                   "Το αρχείο \"%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"             "Αγνόηση"
                   "\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\"." \
                   "Άκυρο όνομα αρχείου \"%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"               "Άνοιγμα"
                   "\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 "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" \
                                        "Άνοιγμα πολλαπλών αρχείων"
    ::msgcat::mcset el "P&aste"              "Επικόλληση"
    ::msgcat::mcset el "Quit"               "Έξοδος"
    ::msgcat::mcset el "&Red"                "Κόκκινο"
                                        "\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 "P&aste"              "\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?" \
                                        "Επικάλυψη υπάρχοντος αρχείου;"
    ::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"    "Επιλογή αρχείου καταγραφής"
                                        "\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" \
                                        "Επιλέξτε αρχείο για εκτέλεση"
    ::msgcat::mcset el "&Selection:"         "Επιλογή:"
    ::msgcat::mcset el "Skip Messages"      "Αποφυγήμηνυμάτων"
    ::msgcat::mcset el "&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 για 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"                "ναι"
    ::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/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
1

2
3


4
5
6
7
8





9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24



25
26
27
28
29

30
31
32
33
34
35
36

37
38
39

40
41



42
43
44
45
46









47
48
49
50
51
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 "&Abort" "&\u0108esigu"
    ::msgcat::mcset eo "&About..." "Pri..."
    ::msgcat::mcset eo "All Files" "Ĉioj dosieroj"
    ::msgcat::mcset eo "Application Error" "Aplikoerraro"
    ::msgcat::mcset eo "All Files" "\u0108iuj dosieroj"
    ::msgcat::mcset eo "Application Error" "Aplikoeraro"
    ::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 "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble \u015dan\u011di al dosierujo \"%1\$s\".\nVi ne rajtas tion."
    ::msgcat::mcset eo "Choose Directory" "Elektu Dosierujon"
    ::msgcat::mcset eo "Cl&ear" "&Vakigu"
    ::msgcat::mcset eo "&Clear Console" "&Vakigu konzolon"
    ::msgcat::mcset eo "Color" "Koloro"
    ::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 "Cu&t" "&Eltondu"
    ::msgcat::mcset eo "&Delete" "&Forigu"
    ::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 \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\n\u0108u vi volas anstata\u016digi la dosieron?"
    ::msgcat::mcset eo "File \"%1\$s\" already exists.\n\n" "La dosiero \"%1\$s\" jam ekzistas. \n\n"
    ::msgcat::mcset eo "File \"%1\$s\" does not exist." "La dosiero \"%1\$s\" ne ekzistas."
    ::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 "Files of &type:" "Dosieroj de &Tipo:"
    ::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 "&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 "Log Files" "Protokolaj dosieroj"
    ::msgcat::mcset eo "&No" "&Ne"
    ::msgcat::mcset eo "&OK"
    ::msgcat::mcset eo "OK"
    ::msgcat::mcset eo "Ok"
    ::msgcat::mcset eo "&OK" "&Bone"
    ::msgcat::mcset eo "OK" "Bone"
    ::msgcat::mcset eo "Ok" "Bone"
    ::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 "Open Multiple Files" "Malfermu plurajn dosierojn"
    ::msgcat::mcset eo "P&aste" "&Algluu"
    ::msgcat::mcset eo "&Quit" "&Forlasu"
    ::msgcat::mcset eo "&Red" "&Ru\u011da"
    ::msgcat::mcset eo "Replace existing file?" "\u0108u anstata\u016digi ekzistantan dosieron?"
    ::msgcat::mcset eo "&Retry" "&Reprovu"
    ::msgcat::mcset eo "&Save" "&Konservu"
    ::msgcat::mcset eo "Save As" "Konservu kiel"
    ::msgcat::mcset eo "Save To Log" "Konservu 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 "Skip Messages" "transsaltu 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 "Tcl for Windows" "Tcl por Vindozo"
    ::msgcat::mcset eo "Text Files" "Tekstodosieroj"
    ::msgcat::mcset eo "&Yes" "&Jes"
    ::msgcat::mcset eo "abort" "ĉesigo"
    ::msgcat::mcset eo "abort" "\u0109esigu"
    ::msgcat::mcset eo "blue" "blua"
    ::msgcat::mcset eo "cancel" "rezignu"
    ::msgcat::mcset eo "extension" "ekspansio"
    ::msgcat::mcset eo "extensions" "ekspansioj"
    ::msgcat::mcset eo "extension" "kromprogramo"
    ::msgcat::mcset eo "extensions" "kromprogramoj"
    ::msgcat::mcset eo "green" "verda"
    ::msgcat::mcset eo "ignore" "ignorieren"
    ::msgcat::mcset eo "red" "ruĝa"
    ::msgcat::mcset eo "retry" "ripetu"
    ::msgcat::mcset eo "ignore" "ignoru"
    ::msgcat::mcset eo "red" "ru\u011da"
    ::msgcat::mcset eo "retry" "reprovu"
    ::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
1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46

47
48
49
50

51
52
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 "Application Error" "Error de la aplicaci\u00f3n"
    ::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.\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álido \"%1\$s\"."
    ::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"
    ::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 "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?" "¿Reemplazar el archivo existente?"
    ::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ón:"
    ::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í"
    ::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ón"
    ::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"
    ::msgcat::mcset es "red" "rojo"
    ::msgcat::mcset es "retry" "reintentar"
    ::msgcat::mcset es "yes" "sí"
    ::msgcat::mcset es "yes" "s\u00ed"
}
Added library/msgs/fi.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
namespace eval ::tk {
    ::msgcat::mcset fi "&Abort" "&Keskeyt\u00e4"
    ::msgcat::mcset fi "&About..." "&Tietoja..."
    ::msgcat::mcset fi "All Files" "Kaikki tiedostot"
    ::msgcat::mcset fi "Application Error" "Ohjelmavirhe"
    ::msgcat::mcset fi "&Apply" "K\u00e4&yt\u00e4"
    ::msgcat::mcset fi "Bold" "Lihavoitu"
    ::msgcat::mcset fi "Bold Italic" "Lihavoitu, kursivoitu"
    ::msgcat::mcset fi "&Blue" "&Sininen"
    ::msgcat::mcset fi "Cancel" "Peruuta"
    ::msgcat::mcset fi "&Cancel" "&Peruuta"
    ::msgcat::mcset fi "Cannot change to the directory \"%1\$s\".\nPermission denied." "Ei voitu vaihtaa hakemistoon \"%1\$s\".\nLupa ev\u00e4tty."
    ::msgcat::mcset fi "Choose Directory" "Valitse hakemisto"
    ::msgcat::mcset fi "Cl&ear" "&Tyhjenn\u00e4"
    ::msgcat::mcset fi "&Clear Console" "&Tyhjenn\u00e4 konsoli"
    ::msgcat::mcset fi "Color" "V\u00e4ri"
    ::msgcat::mcset fi "Console" "Konsoli"
    ::msgcat::mcset fi "&Copy" "K&opioi"
    ::msgcat::mcset fi "Cu&t" "&Leikkaa"
    ::msgcat::mcset fi "&Delete" "&Poista"
    ::msgcat::mcset fi "Details >>" "Lis\u00e4tiedot >>"
    ::msgcat::mcset fi "Directory \"%1\$s\" does not exist." "Hakemistoa \"%1\$s\" ei ole olemassa."
    ::msgcat::mcset fi "&Directory:" "&Hakemisto:"
    ::msgcat::mcset fi "&Edit" "&Muokkaa"
    ::msgcat::mcset fi "Effects" "Tehosteet"
    ::msgcat::mcset fi "Error: %1\$s" "Virhe: %1\$s"
    ::msgcat::mcset fi "E&xit" "&Lopeta"
    ::msgcat::mcset fi "&File" "&Tiedosto"
    ::msgcat::mcset fi "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Tiedosto \"%1\$s\" on jo olemassa.\nHaluatko korvata sen?"
    ::msgcat::mcset fi "File \"%1\$s\" already exists.\n\n" "Tiedosto \"%1\$s\" on jo olemassa.\n\n"
    ::msgcat::mcset fi "File \"%1\$s\" does not exist." "Tiedostoa \"%1\$s\" ei ole olemassa."
    ::msgcat::mcset fi "File &name:" "Tiedosto&nimi:"
    ::msgcat::mcset fi "File &names:" "Tiedosto&nimet:"
    ::msgcat::mcset fi "Files of &type:" "T&yyppi:"
    ::msgcat::mcset fi "Fi&les:" "Ti&edostot:"
    ::msgcat::mcset fi "&Filter" "&Suodata"
    ::msgcat::mcset fi "Fil&ter:" "Suo&data:"
    ::msgcat::mcset fi "Font" "Kirjasin"
    ::msgcat::mcset fi "&Font:" "&Kirjasin:"
    ::msgcat::mcset fi "Font st&yle:" "Kirjasint&yyli:"
    ::msgcat::mcset fi "&Green" "&Vihre\u00e4"
    ::msgcat::mcset fi "&Help" "&Ohje"
    ::msgcat::mcset fi "Hi" "Hei"
    ::msgcat::mcset fi "&Hide Console" "P&iilota konsoli"
    ::msgcat::mcset fi "&Ignore" "&Ohita"
    ::msgcat::mcset fi "Invalid file name \"%1\$s\"." "Virheellinen tiedostonimi \"%1\$s\"."
    ::msgcat::mcset fi "Italic" "Kursivoitu"
    ::msgcat::mcset fi "Log Files" "Lokitiedostot"
    ::msgcat::mcset fi "&No" "&Ei"
    ::msgcat::mcset fi "&OK"
    ::msgcat::mcset fi "OK"
    ::msgcat::mcset fi "Ok" "OK"
    ::msgcat::mcset fi "Open" "Avaa"
    ::msgcat::mcset fi "&Open" "&Avaa"
    ::msgcat::mcset fi "Open Multiple Files" "Avaa monta tiedostoa"
    ::msgcat::mcset fi "P&aste" "L&iit\u00e4"
    ::msgcat::mcset fi "&Quit" "&Lopeta"
    ::msgcat::mcset fi "&Red" "&Punainen"
    ::msgcat::mcset fi "Regular" "Tavallinen"
    ::msgcat::mcset fi "Replace existing file?" "Korvataanko olemassaoleva tiedosto?"
    ::msgcat::mcset fi "&Retry" "&Yrit\u00e4 uudelleen"
    ::msgcat::mcset fi "Sample" "Malli"
    ::msgcat::mcset fi "&Save" "&Tallenna"
    ::msgcat::mcset fi "Save As" "Tallenna nimell\u00e4"
    ::msgcat::mcset fi "Save To Log" "Tallenna lokiin"
    ::msgcat::mcset fi "Select Log File" "Valitse lokitiedosto"
    ::msgcat::mcset fi "Select a file to source" "Valitse l\u00e4hdetiedosto"
    ::msgcat::mcset fi "&Selection:" "&Valinta:"
    ::msgcat::mcset fi "&Size:" "K&oko:"
    ::msgcat::mcset fi "Skip Messages" "J\u00e4t\u00e4 viestit huomiotta"
    ::msgcat::mcset fi "&Source..." "L&\u00e4hde..."
    ::msgcat::mcset fi "Stri&keout" "&Yliviivaa"
    ::msgcat::mcset fi "Tcl Scripts" "Tcl-skriptit"
    ::msgcat::mcset fi "Tcl for Windows" "Tcl Windowsille"
    ::msgcat::mcset fi "Text Files" "Tekstitiedostot"
    ::msgcat::mcset fi "&Underline" "&Alleviivaa"
    ::msgcat::mcset fi "&Yes" "&Kyll\u00e4"
    ::msgcat::mcset fi "abort" "keskeyt\u00e4"
    ::msgcat::mcset fi "blue" "sininen"
    ::msgcat::mcset fi "cancel" "peruuta"
    ::msgcat::mcset fi "extension" "lis\u00e4osa"
    ::msgcat::mcset fi "extensions" "lis\u00e4osat"
    ::msgcat::mcset fi "green" "vihre\u00e4"
    ::msgcat::mcset fi "ignore" "ohita"
    ::msgcat::mcset fi "ok"
    ::msgcat::mcset fi "red" "punainen"
    ::msgcat::mcset fi "retry" "yrit\u00e4 uudelleen"
    ::msgcat::mcset fi "yes" "kyll\u00e4"
}
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
1
2

3
4
5
6
7
8


9
10
11
12
13
14
15
16



17
18
19
20
21


22
23
24
25
26
27
28
29
30


-
+





-
-
+
+






-
-
-
+
+
+


-
-
+
+







namespace eval ::tk {
    ::msgcat::mcset fr "&Abort" "&Annuler"
    ::msgcat::mcset fr "About..." "À propos..."
    ::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 "&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 "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 "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 "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 "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\" 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:"
41
42
43
44
45
46
47
48

49
50
51
52
53
54


55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
41
42
43
44
45
46
47

48
49
50
51
52


53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72







-
+




-
-
+
+

-
+













-
+


    ::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 "&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 à évaluer"
    ::msgcat::mcset fr "&Selection:" "&Sélection:"
    ::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..." "Évaluer..."
    ::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éessayer"
    ::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
1












2
3
4
5
6
7
8
9
10
11
12
13
14






15
16
17
18
19
20
21
22












23
24
25
26
27
28
29
30
31
32
33
34
35





36
37
38
39
40
41
42
43
44


















45
46
47
48
49
50
51
52
53
54
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 "&Abort" "&Megszak\u00edt\u00e1s"
    ::msgcat::mcset hu "&About..." "N\u00e9vjegy..."
    ::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\u00e9gsem"
    ::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 "Cl&ear" "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á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 "&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é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 "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" "Ü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 "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 "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 "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övegfájlok"
    ::msgcat::mcset hu "Text Files" "Sz\u00f6vegf\u00e1jlok"
    ::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 "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örös"
    ::msgcat::mcset hu "retry" "újra"
    ::msgcat::mcset hu "red" "v\u00f6r\u00f6s"
    ::msgcat::mcset hu "retry" "\u00fajra"
    ::msgcat::mcset hu "yes" "igen"
}
Changes to library/msgs/it.msg.
16
17
18
19
20
21
22
23
24


25
26
27
28
29
30
31
16
17
18
19
20
21
22


23
24
25
26
27
28
29
30
31







-
-
+
+







    ::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\" 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:"
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72

73
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
70
71

72
73







-
+










-
+

    ::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 "&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ì"
    ::msgcat::mcset it "yes" "s\u00ec"
}
Changes to library/msgs/nl.msg.
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50







-
+








-
+















-
+







    ::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 "&Copy" "Kopi\u00ebren"
    ::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 "E&xit" "Be\u00ebindigen"
    ::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" "Hé"
    ::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 "Italic" "Cursief"
    ::msgcat::mcset nl "Log Files" "Log Bestanden"
    ::msgcat::mcset nl "&No" "&Nee"
    ::msgcat::mcset nl "&OK"
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
1
2
3
4

5
6
7
8
9
10
11

12
13


14
15
16
17
18
19


20
21
22
23
24
25


26
27
28


29
30
31
32

33
34
35
36
37
38
39
40
41
42
43

44
45

46
47
48
49
50
51
52



53
54
55
56

57
58
59



60
61
62
63
64
65
66
67

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 "Application Error" "B\u0142\u0105d 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 "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ść"
    ::msgcat::mcset pl "&Clear Console" "&Wyczyść konsolę"
    ::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ń"
    ::msgcat::mcset pl "Details >>" "Szczegóły >>"
    ::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 "Effects" "Efekty"
    ::msgcat::mcset pl "Error: %1\$s" "Błąd: %1\$s"
    ::msgcat::mcset pl "E&xit" "&Wyjdź"
    ::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ż 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\" 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ów:"
    ::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 "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 "&Hide Console" "&Ukryj konsol\u0119"
    ::msgcat::mcset pl "&Ignore" "&Ignoruj"
    ::msgcat::mcset pl "Invalid file name \"%1\$s\"." "Niewłaściwa nazwa pliku \"%1\$s\"."
    ::msgcat::mcset pl "Invalid file name \"%1\$s\"." "Niew\u0142a\u015bciwa 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 "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ńcz"
    ::msgcat::mcset pl "&Quit" "&Zako\u0144cz"
    ::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 "Replace existing file?" "Czy zast\u0105pi\u0107 istniej\u0105cy plik?"
    ::msgcat::mcset pl "&Retry" "&Pon\u00f3w"
    ::msgcat::mcset pl "Sample" "Przyk\u0142ad"
    ::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 "&Selection:" "&Wyb\u00f3r:"
    ::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 "Show &Hidden Directories" "Poka\u017c &ukryte katalogi"
    ::msgcat::mcset pl "Show &Hidden Files and Directories" "Poka\u017c &ukryte pliki i katalogi"
    ::msgcat::mcset pl "Skip Messages" "Pomi\u0144 pozosta\u0142e komunikaty"
    ::msgcat::mcset pl "&Source..." "&Kod \u017ar\u00f3d\u0142owy..."
    ::msgcat::mcset pl "Stri&keout" "&Przekre\u015blenie"
    ::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 "&Underline" "Po&dkre\u015blenie"
    ::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 "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
1
2
3
4

5
6
7
8


9
10
11
12
13
14
15
16
17
18


19
20
21
22
23



24
25
26
27
28
29
30
31
32
33
34
35
36

37
38

39
40
41
42
43
44

45
46
47
48
49
50
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 "Application Error" "Erro de aplica\u00e7\u00e3o"
    ::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 "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 "Choose Directory" "Escolha um diret\u00f3rio"
    ::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 "Directory \"%1\$s\" does not exist." "O diret\u00f3rio \"%1\$s\" n\u00e3o existe."
    ::msgcat::mcset pt "&Directory:" "&Diret\u00f3rio:"
    ::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 \"%1\$s\" already exists.\nDo you want to overwrite it?" "O arquivo \"%1\$s\" j\u00e1 existe.\nDeseja sobrescreve-lo?"
    ::msgcat::mcset pt "File \"%1\$s\" already exists.\n\n" "O arquivo \"%1\$s\" j\u00e1 existe.\n\n"
    ::msgcat::mcset pt "File \"%1\$s\" does not exist." "Arquivo \"%1\$s\" n\u00e3o 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 "Invalid file name \"%1\$s\"." "O nome do arquivo \u00e9 inv\u00e1lido \"%1\$s\"."
    ::msgcat::mcset pt "Log Files" "Arquivos de log"
    ::msgcat::mcset pt "&No" "&Não"
    ::msgcat::mcset pt "&No" "&N\u00e3o"
    ::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 "Open Multiple Files" "Abrir m\u00faltiplos 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 "&Selection:" "&Sele\u00e7\u00e3o:"
    ::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 "extension" "extens\u00e3o"
    ::msgcat::mcset pt "extensions" "extens\u00f5es"
    ::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"
}
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
1







2
3
4
5
6
7
8
9
10
11
12













13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


















































31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93


-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
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 "&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 "&Apply" "&\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c"
    ::msgcat::mcset ru "Bold" "Bold"
    ::msgcat::mcset ru "Bold Italic" "Bold Italic"
    ::msgcat::mcset ru "&Blue" " &\u0413\u043e\u043b\u0443\u0431\u043e\u0439"
    ::msgcat::mcset ru "Cancel" "\u041e\u0442\u043c\u0435\u043d\u0430"
    ::msgcat::mcset ru "&Cancel" "\u041e\u0442&\u043c\u0435\u043d\u0430"
    ::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" "Выход"
			"\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 "Cl&ear" "\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c"
    ::msgcat::mcset ru "&Clear Console" "&Clear Console"
    ::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 "Cu&t" "\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 "&Edit" "&Edit"
    ::msgcat::mcset ru "Effects" "\u042d\u0444\u0444\u0435\u043a\u0442\u044b"
    ::msgcat::mcset ru "Error: %1\$s" "\u041e\u0448\u0438\u0431\u043a\u0430: %1\$s"
    ::msgcat::mcset ru "E&xit" "\u0412\u044b\u0445\u043e\u0434"
    ::msgcat::mcset ru "&File" "&File"
    ::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" "да"
			    "\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 "Font" "\u0428\u0440\u0438\u0444\u0442"
    ::msgcat::mcset ru "&Font:" "&\u0428\u0440\u0438\u0444\u0442"
    ::msgcat::mcset ru "Font st&yle:" "&\u0421\u0442\u0438\u043b\u044c \u0448\u0440\u0438\u0444\u0442\u0430:"
    ::msgcat::mcset ru "&Green" " &\u0417\u0435\u043b\u0435\u043d\u044b\u0439"
    ::msgcat::mcset ru "&Help" "&Help"
    ::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 "Italic" "Italic"
    ::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" "\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 "P&aste" "\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 "Regular" "Regular"
    ::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 "Sample" "\u041f\u0440\u0438\u043c\u0435\u0440"
    ::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 "&Size:" "&\u0420\u0430\u0437\u043c\u0435\u0440:"
    ::msgcat::mcset ru "Show &Hidden Directories" "Show &Hidden Directories"
    ::msgcat::mcset ru "Show &Hidden Files and Directories" "Show &Hidden Files and Directories"
    ::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 "Stri&keout" "\u041f&\u0435\u0440\u0435\u0447\u0451\u0440\u043a\u043d\u0443\u0442\u044b\u0439"
    ::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 "&Underline" "\u041f\u043e&\u0434\u0447\u0435\u0440\u043a\u043d\u0443\u0442\u044b\u0439"
    ::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
1
2
3
4
5

6
7
8


9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33


34
35
36

37
38
39
40
41
42
43
44



45
46
47
48
49



50
51
52
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 "&Blue" "&Bl\u00e5"
    ::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 "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 "Cl&ear" "&Radera"
    ::msgcat::mcset sv "&Clear Console" "&Radera konsollen"
    ::msgcat::mcset sv "Color" "Färg"
    ::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 över den?"
    ::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ön"
    ::msgcat::mcset sv "&Help" "&Hjälp"
    ::msgcat::mcset sv "&Green" "&Gr\u00f6n"
    ::msgcat::mcset sv "&Help" "&Hj\u00e4lp"
    ::msgcat::mcset sv "Hi" "Hej"
    ::msgcat::mcset sv "&Hide Console" "&Göm konsollen"
    ::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 "Ok"
    ::msgcat::mcset sv "Open" "Öppna"
    ::msgcat::mcset sv "&Open" "&Öppna"
    ::msgcat::mcset sv "Open Multiple Files" "Öppna flera filer"
    ::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öd"
    ::msgcat::mcset sv "Replace existing file?" "Ersätt existerande fil?"
    ::msgcat::mcset sv "&Retry" "&Försök igen"
    ::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älj loggfil"
    ::msgcat::mcset sv "Select a file to source" "Välj källfil"
    ::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 över meddelanden"
    ::msgcat::mcset sv "&Source..." "&Källa..."
    ::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ör Windows"
    ::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å"
    ::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ön"
    ::msgcat::mcset sv "green" "gr\u00f6n"
    ::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 "red" "r\u00f6d"
    ::msgcat::mcset sv "retry" "f\u00f6rs\u00f6k igen"
    ::msgcat::mcset sv "yes" "ja"
}
Added library/msgs/zh_cn.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
92
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
namespace eval ::tk {
    ::msgcat::mcset zh_cn "&Abort" "&中止"
    ::msgcat::mcset zh_cn "&About..." "&关于……"
    ::msgcat::mcset zh_cn "All Files" "所有文件"
    ::msgcat::mcset zh_cn "Application Error" "应用程序错误"
    ::msgcat::mcset zh_cn "&Apply" "&添加"
    ::msgcat::mcset zh_cn "Bold" "粗体"
    ::msgcat::mcset zh_cn "Bold Italic" "加粗斜体"
    ::msgcat::mcset zh_cn "&Blue" "&蓝色"
    ::msgcat::mcset zh_cn "Cancel" "取消"
    ::msgcat::mcset zh_cn "&Cancel" "&取消"
    ::msgcat::mcset zh_cn "Cannot change to the directory \"%1\$s\".\nPermission denied." "无法更改目录 \"%1\$s\"。\n访问被拒绝。"
    ::msgcat::mcset zh_cn "Choose Directory" "选择文件夹"
    ::msgcat::mcset zh_cn "Cl&ear" "清&除"
    ::msgcat::mcset zh_cn "&Clear Console" "&清除终端"
    ::msgcat::mcset zh_cn "Color" "颜色"
    ::msgcat::mcset zh_cn "Console" "终端"
    ::msgcat::mcset zh_cn "&Copy" "&复制"
    ::msgcat::mcset zh_cn "Cu&t" "剪&切"
    ::msgcat::mcset zh_cn "&Delete" "&删除"
    ::msgcat::mcset zh_cn "Details >>" "详细信息 >>"
    ::msgcat::mcset zh_cn "Directory \"%1\$s\" does not exist." "目录 \"%1\$s\" 不存在。"
    ::msgcat::mcset zh_cn "&Directory:" "&目录:"
    ::msgcat::mcset zh_cn "&Edit" "&编辑"
    ::msgcat::mcset zh_cn "Effects" "效果"
    ::msgcat::mcset zh_cn "Error: %1\$s" "错误: %1\$s"
    ::msgcat::mcset zh_cn "E&xit" "退&出"
    ::msgcat::mcset zh_cn "&File" "&文件"
    ::msgcat::mcset zh_cn "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "文件 \"%1\$s\" 已经存在。\n您想要覆盖它吗?"
    ::msgcat::mcset zh_cn "File \"%1\$s\" already exists.\n\n" "文件 \"%1\$s\" 已经存在。\n\n"
    ::msgcat::mcset zh_cn "File \"%1\$s\" does not exist." "文件 \"%1\$s\" 不存在。"
    ::msgcat::mcset zh_cn "File &name:" "文件&名:"
    ::msgcat::mcset zh_cn "File &names:" "文件&名:"
    ::msgcat::mcset zh_cn "Files of &type:" "文件&类型:"
    ::msgcat::mcset zh_cn "Fi&les:" "文&件:"
    ::msgcat::mcset zh_cn "&Filter" "&过滤"
    ::msgcat::mcset zh_cn "Fil&ter:" "过&滤:"
    ::msgcat::mcset zh_cn "Font" "字体"
    ::msgcat::mcset zh_cn "&Font:" "&字体:"
    ::msgcat::mcset zh_cn "Font st&yle:" "字体&样式:"
    ::msgcat::mcset zh_cn "&Green" "&绿色"
    ::msgcat::mcset zh_cn "&Help" "&帮助"
    ::msgcat::mcset zh_cn "Hi" "你好"
    ::msgcat::mcset zh_cn "&Hide Console" "&隐藏终端"
    ::msgcat::mcset zh_cn "&Ignore" "&忽略"
    ::msgcat::mcset zh_cn "Invalid file name \"%1\$s\"." "无效的文件名 \"%1\$s\"。"
    ::msgcat::mcset zh_cn "Italic" "斜体"
    ::msgcat::mcset zh_cn "Log Files" "日志文件"
    ::msgcat::mcset zh_cn "&No" "&否"
    ::msgcat::mcset zh_cn "&OK" "&确定"
    ::msgcat::mcset zh_cn "OK" "确定"
    ::msgcat::mcset zh_cn "Ok" "确定"
    ::msgcat::mcset zh_cn "Open" "打开"
    ::msgcat::mcset zh_cn "&Open" "&打开"
    ::msgcat::mcset zh_cn "Open Multiple Files" "打开多个文件"
    ::msgcat::mcset zh_cn "P&aste" "粘&贴"
    ::msgcat::mcset zh_cn "&Quit" "&退出"
    ::msgcat::mcset zh_cn "&Red" "红色"
    ::msgcat::mcset zh_cn "Regular" "规则"
    ::msgcat::mcset zh_cn "Replace existing file?" "替换已有文件?"
    ::msgcat::mcset zh_cn "&Retry" "&重试"
    ::msgcat::mcset zh_cn "Sample" "样式"
    ::msgcat::mcset zh_cn "&Save" "&保存"
    ::msgcat::mcset zh_cn "Save As" "另存为"
    ::msgcat::mcset zh_cn "Save To Log" "保存到日志"
    ::msgcat::mcset zh_cn "Select Log File" "选择日志文件"
    ::msgcat::mcset zh_cn "Select a file to source" "选择一个源文件"
    ::msgcat::mcset zh_cn "&Selection:" "&选择:"
    ::msgcat::mcset zh_cn "&Size:" "&大小:"
    ::msgcat::mcset zh_cn "Show &Hidden Directories" "显示&隐藏目录"
    ::msgcat::mcset zh_cn "Show &Hidden Files and Directories" "显示&隐藏文件和目录"
    ::msgcat::mcset zh_cn "Skip Messages" "跳过信息"
    ::msgcat::mcset zh_cn "&Source..." "&来源……"
    ::msgcat::mcset zh_cn "Stri&keout" "删&除线"
    ::msgcat::mcset zh_cn "Tcl Scripts" "Tcl脚本"
    ::msgcat::mcset zh_cn "Tcl for Windows" "适用于Windows的Tcl"
    ::msgcat::mcset zh_cn "Text Files" "文本文档"
    ::msgcat::mcset zh_cn "&Underline" "&下划线"
    ::msgcat::mcset zh_cn "&Yes" "&确定"
    ::msgcat::mcset zh_cn "abort" "中止"
    ::msgcat::mcset zh_cn "blue" "蓝色"
    ::msgcat::mcset zh_cn "cancel" "取消"
    ::msgcat::mcset zh_cn "extension" "拓展"
    ::msgcat::mcset zh_cn "extensions" "拓展"
    ::msgcat::mcset zh_cn "green" "绿色"
    ::msgcat::mcset zh_cn "ignore" "忽略"
    ::msgcat::mcset zh_cn "ok" "确定"
    ::msgcat::mcset zh_cn "red" "红色"
    ::msgcat::mcset zh_cn "retry" "重试"
    ::msgcat::mcset zh_cn "yes" "确认"
}

Changes to library/obsolete.tcl.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
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.
# 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
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> {
    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
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.
# 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
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.
# 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
Changes to library/safetk.tcl.
1
2
3
4
5

6
7
8
9
10
11
12
1
2
3
4

5
6
7
8
9
10
11
12




-
+







# safetk.tcl --
#
# Support procs to use Tk in safe interpreters.
#
# Copyright © 1997 Sun Microsystems, Inc.
# Copyright (c) 1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

# see safetk.n for documentation

#
Changes to library/scale.tcl.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
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.
# 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
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+












-
+












+
+
+
+
+
+
+
+
-
+







    if {$tk_strictMotif} {
	%W configure -activebackground $tk::Priv(activeBg)
    }
    if {[%W cget -state] eq "active"} {
	%W configure -state normal
    }
}
bind Scale <Button-1> {
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 <Button-2> {
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-Button-1> {
bind Scale <Control-1> {
    tk::ScaleControlPress %W %x %y
}
bind Scale <<PrevLine>> {
    tk::ScaleIncrement %W up little noRepeat
}
bind Scale <<NextLine>> {
    tk::ScaleIncrement %W down little noRepeat
198
199
200
201
202
203
204

205












206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225


226
227
228

229
230
231
232
233

234
235
236
237
238
239
240
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265







+

+
+
+
+
+
+
+
+
+
+
+
+




















+
+



+





+







# repeat -	Whether and how to auto-repeat the action:  "noRepeat"
#		means don't auto-repeat, "initial" means this is the
#		first action in an auto-repeat sequence, and "again"
#		means this is the second repetition or later.

proc ::tk::ScaleIncrement {w dir big repeat} {
    variable ::tk::Priv

    if {![winfo exists $w]} return

    # give the cancel callback a chance to be serviced if the execution time of
    # the -command script lasts longer than -repeatdelay
    set clockms [clock milliseconds]
    if {$repeat eq "again" &&
            [expr {$clockms - $Priv(clockms)}] > [expr {[$w cget -repeatinterval] * 1.1}]} {
        set Priv(clockms) $clockms
	set Priv(afterId) [after [$w cget -repeatinterval] \
		[list tk::ScaleIncrement $w $dir $big again]]
	return
    }

    if {$big eq "big"} {
	set inc [$w cget -bigincrement]
	if {$inc == 0} {
	    set inc [expr {abs([$w cget -to] - [$w cget -from])/10.0}]
	}
	if {$inc < [$w cget -resolution]} {
	    set inc [$w cget -resolution]
	}
    } else {
	set inc [$w cget -resolution]
    }
    if {([$w cget -from] > [$w cget -to]) ^ ($dir eq "up")} {
        if {$inc > 0} {
            set inc [expr {-$inc}]
        }
    } else {
        if {$inc < 0} {
            set inc [expr {-$inc}]
        }
    }
    # this will run the -command script (if any) during the redrawing
    # of the scale at idle time
    $w set [expr {[$w get] + $inc}]

    if {$repeat eq "again"} {
        set Priv(clockms) $clockms
	set Priv(afterId) [after [$w cget -repeatinterval] \
		[list tk::ScaleIncrement $w $dir $big again]]
    } elseif {$repeat eq "initial"} {
	set delay [$w cget -repeatdelay]
	if {$delay > 0} {
	    set Priv(clockms) $clockms
	    set Priv(afterId) [after $delay \
		    [list tk::ScaleIncrement $w $dir $big again]]
	}
    }
}

# ::tk::ScaleControlPress --
Changes to library/scrlbar.tcl.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
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.
# 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
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62

63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89

90
91
92
93
94
95
96
97







-
+

















-
+


-
+


-
+




















-
+


-
+








bind Scrollbar <Leave> {
    if {$tk_strictMotif && [info exists tk::Priv(activeBg)]} {
	%W configure -activebackground $tk::Priv(activeBg)
    }
    %W activate {}
}
bind Scrollbar <Button-1> {
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 <Button-2> {
bind Scrollbar <2> {
    tk::ScrollButton2Down %W %x %y
}
bind Scrollbar <B1-Button-2> {
bind Scrollbar <B1-2> {
    # Do nothing, since button 1 is already down.
}
bind Scrollbar <B2-Button-1> {
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-Button-1> {
bind Scrollbar <Control-1> {
    tk::ScrollTopBottom %W %x %y
}
bind Scrollbar <Control-Button-2> {
bind Scrollbar <Control-2> {
    tk::ScrollTopBottom %W %x %y
}

bind Scrollbar <<PrevLine>> {
    tk::ScrollByUnits %W v -1
}
bind Scrollbar <<NextLine>> {
125
126
127
128
129
130
131

132
133
134
135
136


































137
138
139
140
141
142
143
125
126
127
128
129
130
131
132





133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173







+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    tk::ScrollToPos %W 0
}
bind Scrollbar <<LineEnd>> {
    tk::ScrollToPos %W 1
}
}

if {[tk windowingsystem] eq "aqua"} {
bind Scrollbar <MouseWheel> {
    tk::ScrollByUnits %W hv %D -30.0
}
bind Scrollbar <Option-MouseWheel> {
    tk::ScrollByUnits %W hv %D -3.0
    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> {
	if {%D >= 0} {
	    tk::ScrollByUnits %W v [expr {-%D/30}]
	} else {
	    tk::ScrollByUnits %W v [expr {(29-%D)/30}]
	}
    }
    bind Scrollbar <Shift-MouseWheel> {
	if {%D >= 0} {
	    tk::ScrollByUnits %W h [expr {-%D/30}]
	} else {
	    tk::ScrollByUnits %W h [expr {(29-%D)/30}]
	}
    }
}

if {[tk windowingsystem] eq "x11"} {
    bind Scrollbar <4> {tk::ScrollByUnits %W v -5}
    bind Scrollbar <5> {tk::ScrollByUnits %W v 5}
    bind Scrollbar <Shift-4> {tk::ScrollByUnits %W h -5}
    bind Scrollbar <Shift-5> {tk::ScrollByUnits %W h 5}
}

# 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.
#
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317

318
319

320
321
322
323
324
325
326
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346

347
348

349
350
351
352
353
354
355
356







-
+







-
+

-
+







#
# 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}} {
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 [expr {$amount/$factor}] units
	uplevel #0 $cmd scroll $amount units
    } else {
	uplevel #0 $cmd [expr {[lindex $info 2] + [expr {$amount/$factor}]}]
	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.
Changes to library/spinbox.tcl.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
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
# 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:
75
76
77
78
79
80
81
82

83
84
85
86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
101
102

103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
75
76
77
78
79
80
81

82
83
84
85
86
87

88
89
90
91
92

93
94
95
96
97

98
99
100
101

102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+





-
+




-
+




-
+



-
+



-
+













-
+







bind Spinbox <<TraverseIn>> {
    %W selection range 0 end
    %W icursor end
}

# Standard Motif bindings:

bind Spinbox <Button-1> {
bind Spinbox <1> {
    ::tk::spinbox::ButtonDown %W %x %y
}
bind Spinbox <B1-Motion> {
    ::tk::spinbox::Motion %W %x %y
}
bind Spinbox <Double-Button-1> {
bind Spinbox <Double-1> {
    ::tk::spinbox::ArrowPress %W %x %y
    set tk::Priv(selectMode) word
    ::tk::spinbox::MouseSelect %W %x sel.first
}
bind Spinbox <Triple-Button-1> {
bind Spinbox <Triple-1> {
    ::tk::spinbox::ArrowPress %W %x %y
    set tk::Priv(selectMode) line
    ::tk::spinbox::MouseSelect %W %x 0
}
bind Spinbox <Shift-Button-1> {
bind Spinbox <Shift-1> {
    set tk::Priv(selectMode) char
    %W selection adjust @%x
}
bind Spinbox <Double-Shift-Button-1> {
bind Spinbox <Double-Shift-1> {
    set tk::Priv(selectMode) word
    ::tk::spinbox::MouseSelect %W %x
}
bind Spinbox <Triple-Shift-Button-1> {
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-Button-1> {
bind Spinbox <Control-1> {
    %W icursor @%x
}

bind Spinbox <<PrevLine>> {
    %W invoke buttonup
}
bind Spinbox <<NextLine>> {
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230







-
+















+







bind Spinbox <<SelectNone>> {
    %W selection clear
}
bind Spinbox <Key> {
    ::tk::EntryInsert %W %A
}

# Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
# Ignore all Alt, Meta, Control, and Mod4 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}
    bind Spinbox <Mod4-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]}
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290




















291
292
293
294
295
296
297
277
278
279
280
281
282
283
284








285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311







+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    if {!$tk_strictMotif} {
	%W delete [::tk::EntryPreviousWord %W insert] insert
    }
}

# A few additional bindings of my own.

if {[tk windowingsystem] ne "aqua"} {
bind Spinbox <Button-2> {
    if {!$tk_strictMotif} {
	::tk::EntryScanMark %W %x
    }
}
bind Spinbox <B2-Motion> {
    if {!$tk_strictMotif} {
	::tk::EntryScanDrag %W %x
    bind Spinbox <2> {
        if {!$tk_strictMotif} {
        ::tk::EntryScanMark %W %x
        }
    }
    bind Spinbox <B2-Motion> {
        if {!$tk_strictMotif} {
        ::tk::EntryScanDrag %W %x
        }
    }
} else {
    bind Spinbox <3> {
        if {!$tk_strictMotif} {
        ::tk::EntryScanMark %W %x
        }
    }
    bind Spinbox <B3-Motion> {
        if {!$tk_strictMotif} {
        ::tk::EntryScanDrag %W %x
        }
    }
}

# ::tk::spinbox::Invoke --
# Invoke an element of the spinbox
#
# Arguments:
572
573
574
575
576
577
578
579

580
586
587
588
589
590
591
592

593
594







-
+

# 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]
	    [expr {[$w index sel.last] - 1}]]
}
Changes to library/tclIndex.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

































































































































































































202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253




















































1
2
3
4
5
6
7
8

































































































































































































9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201




















































202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# Tcl autoload index file, version 2.0
# This file is generated by the "auto_mkindex" command
# and sourced to set up indexing information for one or
# more commands.  Typically each line is a command that
# sets an element in the auto_index array, where the
# element name is the name of a command and the value is
# a script that loads the command.

set auto_index(::tk::dialog::error::Return) [list source [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::Details) [list source [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::SaveToLog) [list source [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::Destroy) [list source [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::bgerror) [list source [file join $dir bgerror.tcl]]
set auto_index(bgerror) [list source [file join $dir bgerror.tcl]]
set auto_index(::tk::ButtonInvoke) [list source [file join $dir button.tcl]]
set auto_index(::tk::ButtonAutoInvoke) [list source [file join $dir button.tcl]]
set auto_index(::tk::CheckRadioInvoke) [list source [file join $dir button.tcl]]
set auto_index(::tk::dialog::file::chooseDir::) [list source [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::Config) [list source [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::OkCmd) [list source [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::DblClick) [list source [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::ListBrowse) [list source [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::Done) [list source [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::color::) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::InitValues) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::Config) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::BuildDialog) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::SetRGBValue) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::XToRgb) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::RgbToX) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::DrawColorScale) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::CreateSelector) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::RedrawFinalColor) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::RedrawColorBars) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::StartMove) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::MoveSelector) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::ReleaseMouse) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::ResizeColorBars) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::HandleSelEntry) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::HandleRGBEntry) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::EnterColorBar) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::LeaveColorBar) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::OkCmd) [list source [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::CancelCmd) [list source [file join $dir clrpick.tcl]]
set auto_index(tclParseConfigSpec) [list source [file join $dir comdlg.tcl]]
set auto_index(tclListValidFlags) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_Create) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_BindIn) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_BindOut) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_Destroy) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_In) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_Out) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::FDGetFileTypes) [list source [file join $dir comdlg.tcl]]
set auto_index(::tk::ConsoleInit) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleSource) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleInvoke) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleHistory) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsolePrompt) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleBind) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleInsert) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleOutput) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleExit) [list source [file join $dir console.tcl]]
set auto_index(::tk::ConsoleAbout) [list source [file join $dir console.tcl]]
set auto_index(tk_dialog) [list source [file join $dir dialog.tcl]]
set auto_index(::tk::EntryClosestGap) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryButton1) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryMouseSelect) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryPaste) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryAutoScan) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryKeySelect) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryInsert) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntryBackspace) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntrySeeInsert) [list source [file join $dir entry.tcl]]
set auto_index(::tk::EntrySetCursor) [list source [file join $dir entry.tcl]]
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]]
set auto_index(::tk::MenuButtonDown) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuLeave) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuInvoke) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuEscape) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuUpArrow) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuDownArrow) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuLeftArrow) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuRightArrow) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuNextMenu) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuNextEntry) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuFind) [list source [file join $dir menu.tcl]]
set auto_index(::tk::TraverseToMenu) [list source [file join $dir menu.tcl]]
set auto_index(::tk::FirstMenu) [list source [file join $dir menu.tcl]]
set auto_index(::tk::TraverseWithinMenu) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuFirstEntry) [list source [file join $dir menu.tcl]]
set auto_index(::tk::MenuFindName) [list source [file join $dir menu.tcl]]
set auto_index(::tk::PostOverPoint) [list source [file join $dir menu.tcl]]
set auto_index(::tk::SaveGrabInfo) [list source [file join $dir menu.tcl]]
set auto_index(::tk::RestoreOldGrab) [list source [file join $dir menu.tcl]]
set auto_index(tk_menuSetFocus) [list source [file join $dir menu.tcl]]
set auto_index(::tk::GenerateMenuSelect) [list source [file join $dir menu.tcl]]
set auto_index(tk_popup) [list source [file join $dir menu.tcl]]
set auto_index(::tk::ensure_psenc_is_loaded) [list source [file join $dir mkpsenc.tcl]]
set auto_index(::tk::MessageBox) [list source [file join $dir msgbox.tcl]]
set auto_index(tk_menuBar) [list source [file join $dir obsolete.tcl]]
set auto_index(tk_bindForTraversal) [list source [file join $dir obsolete.tcl]]
set auto_index(::tk::classic::restore) [list source [file join $dir obsolete.tcl]]
set auto_index(tk_optionMenu) [list source [file join $dir optMenu.tcl]]
set auto_index(tk_setPalette) [list source [file join $dir palette.tcl]]
set auto_index(::tk::RecolorTree) [list source [file join $dir palette.tcl]]
set auto_index(::tk::Darken) [list source [file join $dir palette.tcl]]
set auto_index(tk_bisque) [list source [file join $dir palette.tcl]]
set auto_index(::safe::tkInterpInit) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::loadTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::TkInit) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::allowTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::disallowTk) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::tkDelete) [list source [file join $dir safetk.tcl]]
set auto_index(::safe::tkTopLevel) [list source [file join $dir safetk.tcl]]
set auto_index(::tk::ScaleActivate) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButtonDown) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleDrag) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleEndDrag) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleIncrement) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleControlPress) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButton2Down) [list source [file join $dir scale.tcl]]
set auto_index(::tk::ScrollButtonDown) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollButtonUp) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollSelect) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollStartDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollEndDrag) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollByUnits) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollByPages) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollToPos) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollTopBottom) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollButton2Down) [list source [file join $dir scrlbar.tcl]]
set auto_index(::tk::spinbox::Invoke) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::ClosestGap) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::ButtonDown) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::ButtonUp) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::MouseSelect) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Paste) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Motion) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::AutoScan) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::KeySelect) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Insert) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Backspace) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::SeeInsert) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::SetCursor) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Transpose) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::PreviousWord) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::GetSelection) [list source [file join $dir spinbox.tcl]]
set auto_index(::tk::TearOffMenu) [list source [file join $dir tearoff.tcl]]
set auto_index(::tk::MenuDup) [list source [file join $dir tearoff.tcl]]
set auto_index(::tk::TextClosestGap) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextButton1) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextSelectTo) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextKeyExtend) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextPaste) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextAutoScan) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextSetCursor) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextKeySelect) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextResetAnchor) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextInsert) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextUpDownLine) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextPrevPara) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextNextPara) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextScrollPages) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextTranspose) [list source [file join $dir text.tcl]]
set auto_index(tk_textCopy) [list source [file join $dir text.tcl]]
set auto_index(tk_textCut) [list source [file join $dir text.tcl]]
set auto_index(tk_textPaste) [list source [file join $dir text.tcl]]
set auto_index(::tk::TextNextPos) [list source [file join $dir text.tcl]]
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::dialog::error::Return) [list source -encoding utf-8 [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::Details) [list source -encoding utf-8 [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::SaveToLog) [list source -encoding utf-8 [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::Destroy) [list source -encoding utf-8 [file join $dir bgerror.tcl]]
set auto_index(::tk::dialog::error::bgerror) [list source -encoding utf-8 [file join $dir bgerror.tcl]]
set auto_index(bgerror) [list source -encoding utf-8 [file join $dir bgerror.tcl]]
set auto_index(::tk::ButtonInvoke) [list source -encoding utf-8 [file join $dir button.tcl]]
set auto_index(::tk::ButtonAutoInvoke) [list source -encoding utf-8 [file join $dir button.tcl]]
set auto_index(::tk::CheckRadioInvoke) [list source -encoding utf-8 [file join $dir button.tcl]]
set auto_index(::tk::dialog::file::chooseDir::) [list source -encoding utf-8 [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::Config) [list source -encoding utf-8 [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::OkCmd) [list source -encoding utf-8 [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::DblClick) [list source -encoding utf-8 [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::ListBrowse) [list source -encoding utf-8 [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::file::chooseDir::Done) [list source -encoding utf-8 [file join $dir choosedir.tcl]]
set auto_index(::tk::dialog::color::) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::InitValues) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::Config) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::BuildDialog) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::SetRGBValue) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::XToRgb) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::RgbToX) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::DrawColorScale) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::CreateSelector) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::RedrawFinalColor) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::RedrawColorBars) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::StartMove) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::MoveSelector) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::ReleaseMouse) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::ResizeColorBars) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::HandleSelEntry) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::HandleRGBEntry) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::EnterColorBar) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::LeaveColorBar) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::OkCmd) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(::tk::dialog::color::CancelCmd) [list source -encoding utf-8 [file join $dir clrpick.tcl]]
set auto_index(tclParseConfigSpec) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(tclListValidFlags) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_Create) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_BindIn) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_BindOut) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_Destroy) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_In) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::FocusGroup_Out) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::FDGetFileTypes) [list source -encoding utf-8 [file join $dir comdlg.tcl]]
set auto_index(::tk::ConsoleInit) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleSource) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleInvoke) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleHistory) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsolePrompt) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleBind) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleInsert) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleOutput) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleExit) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(::tk::ConsoleAbout) [list source -encoding utf-8 [file join $dir console.tcl]]
set auto_index(tk_dialog) [list source -encoding utf-8 [file join $dir dialog.tcl]]
set auto_index(::tk::EntryClosestGap) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryButton1) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryMouseSelect) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryPaste) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryAutoScan) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryKeySelect) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryInsert) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryBackspace) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntrySeeInsert) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntrySetCursor) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryTranspose) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryPreviousWord) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(::tk::EntryGetSelection) [list source -encoding utf-8 [file join $dir entry.tcl]]
set auto_index(tk_focusNext) [list source -encoding utf-8 [file join $dir focus.tcl]]
set auto_index(tk_focusPrev) [list source -encoding utf-8 [file join $dir focus.tcl]]
set auto_index(::tk::FocusOK) [list source -encoding utf-8 [file join $dir focus.tcl]]
set auto_index(tk_focusFollowsMouse) [list source -encoding utf-8 [file join $dir focus.tcl]]
set auto_index(::tk::IconList) [list source -encoding utf-8 [file join $dir iconlist.tcl]]
set auto_index(::tk::ListboxBeginSelect) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxMotion) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxBeginExtend) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxBeginToggle) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxAutoScan) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxUpDown) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxExtendUpDown) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxDataExtend) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxCancel) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::ListboxSelectAll) [list source -encoding utf-8 [file join $dir listbox.tcl]]
set auto_index(::tk::Megawidget) [list source -encoding utf-8 [file join $dir megawidget.tcl]]
set auto_index(::tk::MbEnter) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MbLeave) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MbPost) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuUnpost) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MbMotion) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MbButtonUp) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuMotion) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuButtonDown) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuLeave) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuInvoke) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuEscape) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuUpArrow) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuDownArrow) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuLeftArrow) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuRightArrow) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuNextMenu) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuNextEntry) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuFind) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::TraverseToMenu) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::FirstMenu) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::TraverseWithinMenu) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuFirstEntry) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::MenuFindName) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::PostOverPoint) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::SaveGrabInfo) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::RestoreOldGrab) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(tk_menuSetFocus) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::GenerateMenuSelect) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(tk_popup) [list source -encoding utf-8 [file join $dir menu.tcl]]
set auto_index(::tk::ensure_psenc_is_loaded) [list source -encoding utf-8 [file join $dir mkpsenc.tcl]]
set auto_index(::tk::MessageBox) [list source -encoding utf-8 [file join $dir msgbox.tcl]]
set auto_index(tk_menuBar) [list source -encoding utf-8 [file join $dir obsolete.tcl]]
set auto_index(tk_bindForTraversal) [list source -encoding utf-8 [file join $dir obsolete.tcl]]
set auto_index(::tk::classic::restore) [list source -encoding utf-8 [file join $dir obsolete.tcl]]
set auto_index(tk_optionMenu) [list source -encoding utf-8 [file join $dir optMenu.tcl]]
set auto_index(tk_setPalette) [list source -encoding utf-8 [file join $dir palette.tcl]]
set auto_index(::tk::RecolorTree) [list source -encoding utf-8 [file join $dir palette.tcl]]
set auto_index(::tk::Darken) [list source -encoding utf-8 [file join $dir palette.tcl]]
set auto_index(tk_bisque) [list source -encoding utf-8 [file join $dir palette.tcl]]
set auto_index(::safe::tkInterpInit) [list source -encoding utf-8 [file join $dir safetk.tcl]]
set auto_index(::safe::loadTk) [list source -encoding utf-8 [file join $dir safetk.tcl]]
set auto_index(::safe::TkInit) [list source -encoding utf-8 [file join $dir safetk.tcl]]
set auto_index(::safe::allowTk) [list source -encoding utf-8 [file join $dir safetk.tcl]]
set auto_index(::safe::disallowTk) [list source -encoding utf-8 [file join $dir safetk.tcl]]
set auto_index(::safe::tkDelete) [list source -encoding utf-8 [file join $dir safetk.tcl]]
set auto_index(::safe::tkTopLevel) [list source -encoding utf-8 [file join $dir safetk.tcl]]
set auto_index(::tk::ScaleActivate) [list source -encoding utf-8 [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButtonDown) [list source -encoding utf-8 [file join $dir scale.tcl]]
set auto_index(::tk::ScaleDrag) [list source -encoding utf-8 [file join $dir scale.tcl]]
set auto_index(::tk::ScaleEndDrag) [list source -encoding utf-8 [file join $dir scale.tcl]]
set auto_index(::tk::ScaleIncrement) [list source -encoding utf-8 [file join $dir scale.tcl]]
set auto_index(::tk::ScaleControlPress) [list source -encoding utf-8 [file join $dir scale.tcl]]
set auto_index(::tk::ScaleButton2Down) [list source -encoding utf-8 [file join $dir scale.tcl]]
set auto_index(::tk::ScrollButtonDown) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollButtonUp) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollSelect) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollStartDrag) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollDrag) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollEndDrag) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollByUnits) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollByPages) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollToPos) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollTopBottom) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::ScrollButton2Down) [list source -encoding utf-8 [file join $dir scrlbar.tcl]]
set auto_index(::tk::spinbox::Invoke) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::ClosestGap) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::ButtonDown) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::ButtonUp) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::MouseSelect) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Paste) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Motion) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::AutoScan) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::KeySelect) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Insert) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Backspace) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::SeeInsert) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::SetCursor) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::Transpose) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::PreviousWord) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::spinbox::GetSelection) [list source -encoding utf-8 [file join $dir spinbox.tcl]]
set auto_index(::tk::TearOffMenu) [list source -encoding utf-8 [file join $dir tearoff.tcl]]
set auto_index(::tk::MenuDup) [list source -encoding utf-8 [file join $dir tearoff.tcl]]
set auto_index(::tk::TextClosestGap) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextButton1) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextSelectTo) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextKeyExtend) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextPaste) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextAutoScan) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextSetCursor) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextKeySelect) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextResetAnchor) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextInsert) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextUpDownLine) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextPrevPara) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextNextPara) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextScrollPages) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextTranspose) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(tk_textCopy) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(tk_textCut) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(tk_textPaste) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextNextPos) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::TextPrevPos) [list source -encoding utf-8 [file join $dir text.tcl]]
set auto_index(::tk::PlaceWindow) [list source -encoding utf-8 [file join $dir tk.tcl]]
set auto_index(::tk::SetFocusGrab) [list source -encoding utf-8 [file join $dir tk.tcl]]
set auto_index(::tk::RestoreFocusGrab) [list source -encoding utf-8 [file join $dir tk.tcl]]
set auto_index(::tk::ScreenChanged) [list source -encoding utf-8 [file join $dir tk.tcl]]
set auto_index(::tk::EventMotifBindings) [list source -encoding utf-8 [file join $dir tk.tcl]]
set auto_index(::tk::CancelRepeat) [list source -encoding utf-8 [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]]
set auto_index(::tk::dialog::file::SetPath) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetFilter) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ResolveFile) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::EntFocusIn) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::EntFocusOut) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ActivateEnt) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::VerifyFileName) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::InvokeBtn) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::UpDirCmd) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::JoinFile) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::OkCmd) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::CancelCmd) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ListBrowse) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ListInvoke) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Done) [list source [file join $dir tkfbox.tcl]]
set auto_index(::tk::MotifFDialog) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_Create) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_FileTypes) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_SetFilter) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_Config) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_BuildUI) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_SetListMode) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_MakeSList) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_InterpFilter) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_Update) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_LoadFiles) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_BrowseDList) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateDList) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_BrowseFList) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateFList) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateFEnt) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateSEnt) [list source [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_OkCmd) [list source [file join $dir xmfbox.tcl]]
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]]
set auto_index(::tk::TabToWindow) [list source -encoding utf-8 [file join $dir tk.tcl]]
set auto_index(::tk::dialog::file::) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Config) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Create) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetSelectMode) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::UpdateWhenIdle) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Update) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetPathSilently) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetPath) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::SetFilter) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ResolveFile) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::EntFocusIn) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::EntFocusOut) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ActivateEnt) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::VerifyFileName) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::InvokeBtn) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::UpDirCmd) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::JoinFile) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::OkCmd) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::CancelCmd) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ListBrowse) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::ListInvoke) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::dialog::file::Done) [list source -encoding utf-8 [file join $dir tkfbox.tcl]]
set auto_index(::tk::MotifFDialog) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_Create) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_FileTypes) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_SetFilter) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_Config) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_BuildUI) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_SetListMode) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_MakeSList) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_InterpFilter) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_Update) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_LoadFiles) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_BrowseDList) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateDList) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_BrowseFList) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateFList) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateFEnt) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_ActivateSEnt) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_OkCmd) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_FilterCmd) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::MotifFDialog_CancelCmd) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Set) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Unset) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Key) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Goto) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::ListBoxKeyAccel_Reset) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(tk_getFileType) [list source -encoding utf-8 [file join $dir xmfbox.tcl]]
set auto_index(::tk::unsupported::ExposePrivateCommand) [list source -encoding utf-8 [file join $dir unsupported.tcl]]
set auto_index(::tk::unsupported::ExposePrivateVariable) [list source -encoding utf-8 [file join $dir unsupported.tcl]]
set auto_index(::tk::fontchooser) [list source -encoding utf-8 [file join $dir fontchooser.tcl]]
Changes to library/tearoff.tcl.
1
2
3
4
5
6


7
8
9
10
11
12
13
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.
# 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
27
28
29
30
31
32
33
34

35
36
37

38
39
40
41
42
43
44
27
28
29
30
31
32
33

34
35
36

37
38
39
40
41
42
43
44







-
+


-
+







    # the parent of the new menu.  This guarantees that the torn off
    # menu will be on the same screen as the original menu.  By making
    # it a child of the ancestor, rather than a child of the menu, it
    # can continue to live even if the menu is deleted;  it will go
    # away when the toplevel goes away.

    if {$x == 0} {
    	set x [winfo rootx $w]
	set x [winfo rootx $w]
    }
    if {$y == 0} {
    	set y [winfo rooty $w]
	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}
	}
    }
62
63
64
65
66
67
68
69

70
71

72
73

74
75
76

77
78
79
80
81
82
83
84
85
86





87
88
89
90
91
92
93
62
63
64
65
66
67
68

69
70

71
72

73
74
75

76
77
78
79
80
81





82
83
84
85
86
87
88
89
90
91
92
93







-
+

-
+

-
+


-
+





-
-
-
-
-
+
+
+
+
+








    # Pick a title for the new menu by looking at the parent of the
    # original: if the parent is a menu, then use the text of the active
    # entry.  If it's a menubutton then use its text.

    set parent [winfo parent $w]
    if {[$menu cget -title] ne ""} {
    	wm title $menu [$menu cget -title]
	wm title $menu [$menu cget -title]
    } else {
    	switch -- [winfo class $parent] {
	switch -- [winfo class $parent] {
	    Menubutton {
	    	wm title $menu [$parent cget -text]
		wm title $menu [$parent cget -text]
	    }
	    Menu {
	    	wm title $menu [$parent entrycget active -label]
		wm title $menu [$parent entrycget active -label]
	    }
	}
    }

    if {[tk windowingsystem] eq "win32"} {
        # [Bug 3181181]: Find the toplevel window for the menu
        set parent [winfo toplevel $parent]
        while {[winfo class $parent] eq "Menu"} {
            set parent [winfo toplevel [winfo parent $parent]]
        }
	# [Bug 3181181]: Find the toplevel window for the menu
	set parent [winfo toplevel $parent]
	while {[winfo class $parent] eq "Menu"} {
	    set parent [winfo toplevel [winfo parent $parent]]
	}
	wm transient $menu [winfo toplevel $parent]
	wm attributes $menu -toolwindow 1
    }

    $menu post $x $y

    if {[winfo exists $menu] == 0} {
130
131
132
133
134
135
136



137
138

139
140
141
142
143
144
145
146
147
148








149
150
151
152
153

154
155
156
157
158
159
160

161
162
163
164
165




166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
130
131
132
133
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 {[lindex $option 0] eq "-type"} {
	    continue
	}
	lappend cmd [lindex $option 0] [lindex $option 4]
    }
    eval $cmd

    # Copy the meny entries, if any

    set last [$src index last]
    if {$last eq "none"} {
    if {$last ne "none"} {
	return
    }
    for {set i [$src cget -tearoff]} {$i <= $last} {incr i} {
	set cmd [list $dst add [$src type $i]]
	foreach option [$src entryconfigure $i]  {
	    lappend cmd [lindex $option 0] [lindex $option 4]
	}
	eval $cmd
    }

	for {set i [$src cget -tearoff]} {$i <= $last} {incr i} {
	    set cmd [list $dst add [$src type $i]]
	    foreach option [$src entryconfigure $i]  {
		lappend cmd [lindex $option 0] [lindex $option 4]
	    }
	    eval $cmd
	}
    }
    # Duplicate the binding tags and bindings from the source menu.

    set tags [bindtags $src]
    set srcLen [string length $src]

    # Duplicate the binding tags from the source menu, replacing src with dst
    # 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]
    set tags [bindtags $src]
    }
    append x $tags

    bindtags $dst $x

    set x [lsearch -exact $tags $src]
    if {$x >= 0} {lset tags $x $dst}
    bindtags $dst $tags
}
    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
    }
}
Changes to library/text.tcl.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
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.
# 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:
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54

55
56
57
58
59

60
61
62
63
64

65
66
67
68
69

70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53

54
55
56
57
58

59
60
61
62
63

64
65
66
67
68

69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+








-
+




-
+




-
+




-
+



-
+















-
+








-
+







# The code below creates the default class bindings for text widgets.
#-------------------------------------------------------------------------



# Standard Motif bindings:

bind Text <Button-1> {
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-Button-1> {
bind Text <Double-1> {
    set tk::Priv(selectMode) word
    tk::TextSelectTo %W %x %y
    catch {%W mark set insert sel.first}
}
bind Text <Triple-Button-1> {
bind Text <Triple-1> {
    set tk::Priv(selectMode) line
    tk::TextSelectTo %W %x %y
    catch {%W mark set insert sel.first}
}
bind Text <Shift-Button-1> {
bind Text <Shift-1> {
    tk::TextResetAnchor %W @%x,%y
    set tk::Priv(selectMode) char
    tk::TextSelectTo %W %x %y
}
bind Text <Double-Shift-Button-1>	{
bind Text <Double-Shift-1>	{
    set tk::Priv(selectMode) word
    tk::TextSelectTo %W %x %y 1
}
bind Text <Triple-Shift-Button-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-Button-1> {
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-Button-1> { # nothing }
bind Text <Double-Control-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
304
305
306
307
308
309
310

311
312
313
314
315
316
317
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318







+







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}
    bind Text <Mod4-Key> {# nothing}
}

# Additional emacs-like bindings:

bind Text <Control-d> {
    if {!$tk_strictMotif && [%W compare end != insert+1c]} {
	%W delete insert
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439




















440
441
442
443






444
445
446
447
448
449
450
451
452
453
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
426
427
428
429
430
431
432
433








434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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







+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


















+
+
+
+
-
+








bind Text <Control-h> {
    if {!$tk_strictMotif && [%W compare insert != 1.0]} {
	%W delete insert-1c
	%W see insert
    }
}
if {[tk windowingsystem] ne "aqua"} {
bind Text <Button-2> {
    if {!$tk_strictMotif} {
	tk::TextScanMark %W %x %y
    }
}
bind Text <B2-Motion> {
    if {!$tk_strictMotif} {
	tk::TextScanDrag %W %x %y
    bind Text <2> {
        if {!$tk_strictMotif} {
        tk::TextScanMark %W %x %y
        }
    }
    bind Text <B2-Motion> {
        if {!$tk_strictMotif} {
        tk::TextScanDrag %W %x %y
        }
    }
} else {
    bind Text <3> {
        if {!$tk_strictMotif} {
        tk::TextScanMark %W %x %y
        }
    }
    bind Text <B3-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> {
    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
    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
	}
    }
    bind Text <Shift-MouseWheel> {
	if {%D >= 0} {
	    %W xview scroll [expr {-%D/3}] pixels
	} else {
	    %W xview scroll [expr {(2-%D)/3}] pixels
	}
    }
}

if {[tk windowingsystem] eq "x11"} {
    # 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:
    #	https://linuxreviews.org/HOWTO_change_the_mouse_speed_in_X
    bind Text <4> {
	if {!$tk_strictMotif} {
	    %W yview scroll -50 pixels
	}
    }
    bind Text <5> {
	if {!$tk_strictMotif} {
	    %W yview scroll 50 pixels
	}
    }
    bind Text <Shift-4> {
	if {!$tk_strictMotif} {
	    %W xview scroll -50 pixels
	}
    }
    bind Text <Shift-5> {
	if {!$tk_strictMotif} {
	    %W xview 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.
#
# Arguments:
# w -		The text window.
# x -		X-coordinate within the window.
# y -		Y-coordinate within the window.

proc ::tk::TextClosestGap {w x y} {
    set pos [$w index @$x,$y]
    set bbox [$w bbox $pos]
    if {$bbox eq ""} {
	return $pos
    }
    # The check on y coord of the line bbox with dlineinfo is to fix
    # [a9cf210a42] to properly handle selecting and moving the mouse
    # out of the widget.
    if {$y < [lindex [$w dlineinfo $pos] 1] ||
    if {($x - [lindex $bbox 0]) < ([lindex $bbox 2]/2)} {
            $x - [lindex $bbox 0] < [lindex $bbox 2]/2} {
	return $pos
    }
    $w index "$pos + 1 char"
}

# ::tk::TextButton1 --
# This procedure is invoked to handle button-1 presses in text
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
1236
1237
1238
1239
1240
1241
1242




































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
    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
}
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
1
2
3
4
5



6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21





-
-
-
+
+
+





-
+







# 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.
# 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.7a4
package require -exact Tk  8.6.16

# 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}]} {
174
175
176
177
178
179
180

181
182
183
184
185






186



187
188

189
190

191
192
193
194
195
196
197
174
175
176
177
178
179
180
181





182
183
184
185
186
187
188
189
190
191
192

193
194

195
196
197
198
199
200
201
202







+
-
-
-
-
-
+
+
+
+
+
+

+
+
+

-
+

-
+







	unset ::tk::FocusGrab($index)
    } else {
	set oldGrab ""
    }

    catch {focus $oldFocus}
    grab release $grab
    if {[winfo exists $grab]} {
    if {$destroy eq "withdraw"} {
	wm withdraw $grab
    } else {
	destroy $grab
    }
	if {$destroy eq "withdraw"} {
	    wm withdraw $grab
	} else {
	    destroy $grab
	}
    }
    if {[winfo exists $oldGrab] && [winfo ismapped $oldGrab]} {
	# The "grab" command will fail if another application
	# already holds the grab on a window with the same name.
	# So catch it. See [7447ed20ec] for an example.
	if {$oldStatus eq "global"} {
	    grab -global $oldGrab
	    catch {grab -global $oldGrab}
	} else {
	    grab $oldGrab
	    catch {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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323















324
325
326
327
328
329
330
307
308
309
310
311
312
313















314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








    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>
    event $op <<Cut>> <Control-Key-w> <Control-Lock-Key-W> <Shift-Key-Delete>
    event $op <<Copy>> <Meta-Key-w> <Meta-Lock-Key-W> <Control-Key-Insert>
    event $op <<Paste>> <Control-Key-y> <Control-Lock-Key-Y> <Shift-Key-Insert>
    event $op <<PrevChar>> <Control-Key-b> <Control-Lock-Key-B>
    event $op <<NextChar>> <Control-Key-f> <Control-Lock-Key-F>
    event $op <<PrevLine>> <Control-Key-p> <Control-Lock-Key-P>
    event $op <<NextLine>> <Control-Key-n> <Control-Lock-Key-N>
    event $op <<LineStart>> <Control-Key-a> <Control-Lock-Key-A>
    event $op <<LineEnd>> <Control-Key-e> <Control-Lock-Key-E>
    event $op <<SelectPrevChar>> <Control-Key-B> <Control-Lock-Key-b>
    event $op <<SelectNextChar>> <Control-Key-F> <Control-Lock-Key-f>
    event $op <<SelectPrevLine>> <Control-Key-P> <Control-Lock-Key-p>
    event $op <<SelectNextLine>> <Control-Key-N> <Control-Lock-Key-n>
    event $op <<SelectLineStart>> <Control-Key-A> <Control-Lock-Key-a>
    event $op <<SelectLineEnd>> <Control-Key-E> <Control-Lock-Key-e>
}

#----------------------------------------------------------------------
# Define common dialogs on platforms where they are not implemented
# using compiled code.
#----------------------------------------------------------------------

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378







379
380
381
382
383


384
385
386
387
388
389
390
367
368
369
370
371
372
373



374
375





376
377
378
379
380
381
382
383
384
385


386
387
388
389
390
391
392
393
394







-
-
-


-
-
-
-
-
+
+
+
+
+
+
+



-
-
+
+







    }
}

#----------------------------------------------------------------------
# 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>
	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>
	event add <<ContextMenu>>	<Button-3>
	# 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 <<SelectAll>>		<Control-Key-slash>
	event add <<SelectNone>>	<Control-Key-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>
416
417
418
419
420
421
422
423
424
425
426
427







428
429
430


431
432
433
434
435
436
437
420
421
422
423
424
425
426





427
428
429
430
431
432
433
434


435
436
437
438
439
440
441
442
443







-
-
-
-
-
+
+
+
+
+
+
+

-
-
+
+







	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 <<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>
	event add <<ContextMenu>>	<Button-3>

	event add <<SelectAll>>		<Control-slash> <Control-a> <Control-Lock-A>
	event add <<SelectNone>>	<Control-backslash>
	event add <<SelectAll>>		<Control-Key-slash> <Control-Key-a> <Control-Lock-Key-A>
	event add <<SelectNone>>	<Control-Key-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>
447
448
449
450
451
452
453
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
453
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







-
-
-
+
+
+
+

+


-
-
+
+










-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+







	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 <<Cut>>		<Command-Key-x> <Key-F2> <Command-Lock-Key-X>
	event add <<Copy>>		<Command-Key-c> <Key-F3> <Command-Lock-Key-C>
	event add <<Paste>>		<Command-Key-v> <Key-F4> <Command-Lock-Key-V>
	event add <<PasteSelection>>	<ButtonRelease-3>
	event add <<Clear>>		<Clear>
	event add <<ContextMenu>>	<Button-2>

	# Official bindings
	# See http://support.apple.com/kb/HT1343
	event add <<SelectAll>>		<Command-a>
	# See https://support.apple.com/en-us/HT201236
	event add <<SelectAll>>		<Command-Key-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>
	event add <<LineStart>>		<Home> <Command-Left> <Control-Key-a> <Control-Lock-Key-A>
	event add <<SelectLineStart>>	<Shift-Home> <Shift-Command-Left> <Shift-Control-Key-A> <Shift-Control-Lock-Key-A>
	event add <<LineEnd>>		<End> <Command-Right> <Control-Key-e> <Control-Lock-Key-E>
	event add <<SelectLineEnd>>	<Shift-End> <Shift-Command-Right> <Shift-Control-Key-E> <Shift-Control-Lock-Key-E>
	event add <<PrevLine>>		<Up> <Control-Key-p> <Control-Lock-Key-P>
	event add <<SelectPrevLine>>	<Shift-Up> <Shift-Control-Key-P> <Shift-Control-Lock-Key-P>
	event add <<NextLine>>		<Down> <Control-Key-n> <Control-Lock-Key-N>
	event add <<SelectNextLine>>	<Shift-Down> <Shift-Control-Key-N> <Shift-Control-Lock-Key-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>
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
537
538
539
540
541
542
543







544
545
546
547
548
549
550







-
-
-
-
-
-
-








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:
627
628
629
630
631
632
633
634
635


636
637
638
639
640
641
642
628
629
630
631
632
633
634


635
636
637
638
639
640
641
642
643







-
-
+
+







    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]]
    set subwins [concat [grid slaves $path] [pack slaves $path] \
	    [place slaves $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}
	    }
	}
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
676
677
678
679
680
681
682









683
684
685
686
687
688
689







-
-
-
-
-
-
-
-
-







	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} {
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
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20












-
+







# 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.
# 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.
#

namespace eval ::tk::dialog {}
namespace eval ::tk::dialog::file {
222
223
224
225
226
227
228

229


230
231
232
233
234
235
236
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238







+
-
+
+








    # Cleanup traces on selectPath variable
    #

    foreach trace [trace info variable data(selectPath)] {
	trace remove variable data(selectPath) {*}$trace
    }
    if {[winfo exists $data(dirMenuBtn)]} {
    $data(dirMenuBtn) configure -textvariable {}
	$data(dirMenuBtn) configure -textvariable {}
    }

    return $Priv(selectFilePath)
}

# ::tk::dialog::file::Config --
#
#	Configures the TK filedialog according to the argument list
577
578
579
580
581
582
583
584

585
586

587
588
589
590
591
592
593
579
580
581
582
583
584
585

586
587

588
589
590
591
592
593
594
595







-
+

-
+







	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]
    set dlgCursor [$w cget -cursor]
    $data(ent) configure -cursor watch
    $w         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
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645







-
+







	    ::tk::SetAmpText $data(okBtn) [mc "&Save"]
	}
    }

    # turn off the busy cursor.
    #
    $data(ent) configure -cursor $entCursor
    $w         configure -cursor $dlgCursor
    $w configure -cursor $dlgCursor
}

# ::tk::dialog::file::SetPathSilently --
#
# 	Sets data(selectPath) without invoking the trace procedure
#
proc ::tk::dialog::file::SetPathSilently {w path} {
905
906
907
908
909
910
911
912
913


914
915
916
917
918
919
920


921
922
923
924
925
926
927
907
908
909
910
911
912
913


914
915
916
917
918
919
920


921
922
923
924
925
926
927
928
929







-
-
+
+





-
-
+
+







		} else {
		    set data(selectFile) $file
		}
		Done $w
	    }
	}
	PATH {
	    tk_messageBox -icon warning -type ok -parent $w \
		    -message [mc "Directory \"%1\$s\" does not exist." $path]
	    tk_messageBox -icon warning -type ok -parent $w -message \
		    [mc "Directory \"%1\$s\" does not exist." $path]
	    $data(ent) selection range 0 end
	    $data(ent) icursor end
	}
	CHDIR {
	    tk_messageBox -type ok -parent $w -icon warning -message  \
		[mc "Cannot change to the directory\
                     \"%1\$s\".\nPermission denied." $path]
		    [mc "Cannot change to the directory\
			\"%1\$s\".\nPermission denied." $path]
	    $data(ent) selection range 0 end
	    $data(ent) icursor end
	}
	ERROR {
	    tk_messageBox -type ok -parent $w -icon warning -message \
		    [mc "Invalid file name \"%1\$s\"." $path]
	    $data(ent) selection range 0 end
1117
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
1132
1119
1120
1121
1122
1123
1124
1125

1126

1127
1128
1129
1130
1131
1132
1133







-
+
-







	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]
		    [lsearch -exact $data(-filetypes) $data(filterType)] 0]

	}
    }
    bind $data(okBtn) <Destroy> {}
    set Priv(selectFilePath) $selectFilePath
}

# ::tk::dialog::file::GlobFiltered --
Changes to library/ttk/altTheme.tcl.
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61


62
63

64


65
66
67
68

69
70
71


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96


97
98
99
100
101
102
103
104
105


106
107
108
109































22
23
24
25
26
27
28

29

30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63

64
65
66
67
68

69

70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87


88
89
90
91
92

93
94
95

96
97
98
99
100
101
102
103
104


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141







-
+
-










-



















-
+
+


+
-
+
+



-
+
-

-
+
+















-
-
+
+



-



-
+
+







-
-
+
+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
	ttk::style configure "." \
	    -background 	$colors(-frame) \
	    -foreground 	black \
	    -troughcolor	$colors(-darker) \
	    -bordercolor	$colors(-border) \
	    -selectbackground 	$colors(-selectbg) \
	    -selectforeground 	$colors(-selectfg) \
	    -font 		TkDefaultFont \
	    -font 		TkDefaultFont
	    ;

	ttk::style map "." -background \
	    [list disabled $colors(-frame)  active $colors(-activebg)] ;
	ttk::style map "." -foreground [list disabled $colors(-disabledfg)] ;
        ttk::style map "." -embossed [list disabled 1] ;

	ttk::style configure TButton \
	    -anchor center -width -11 -padding "1 1" \
	    -relief raised -shiftrelief 1 \
	    -highlightthickness 1 -highlightcolor $colors(-frame)

	ttk::style map TButton -relief {
	    {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 configure TEntry -padding 1 \
	    -focuswidth 2 -focuscolor $colors(-selectbg)
	ttk::style map TEntry -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -padding 1
	ttk::style configure TCombobox -padding 1 \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	ttk::style map TCombobox -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)] \
		-arrowcolor [list disabled $colors(-disabledfg)]
	ttk::style configure ComboboxPopdownFrame \
	ttk::style configure ComboboxPopdownFrame -relief solid -borderwidth 1
	    -relief solid -borderwidth 1

	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure Toolbutton -relief flat -padding 2
	ttk::style map Toolbutton -relief \
	    {disabled flat selected sunken pressed sunken active raised}
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-darker)  active $colors(-activebg)]

	ttk::style configure TScrollbar -relief raised

	ttk::style configure TLabelframe -relief groove -borderwidth 2

	ttk::style configure TNotebook -tabmargins {2 2 1 0}
	ttk::style configure TNotebook.Tab \
	    -padding {4 2} -background $colors(-darker)
	ttk::style configure TNotebook.Tab -background $colors(-darker) \
	    -padding {4 2}
	ttk::style map TNotebook.Tab \
	    -background [list selected $colors(-frame)] \
	    -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 configure Treeview -background $colors(-window) \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	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
	    -groovewidth 4 -troughrelief sunken -borderwidth 2

	ttk::style configure TProgressbar \
	    -background $colors(-selectbg) -borderwidth 0
    }
}

# ttk::theme::alt::configureNotebookStyle --
#
# Sets theme-specific option values for the ttk::notebook style $style and the
# style $style.Tab.  Invoked by ::ttk::configureNotebookStyle.

proc ttk::theme::alt::configureNotebookStyle {style} {
    set tabPos [ttk::style lookup $style -tabposition {} nw]
    switch -- [string index $tabPos 0] {
	n {
	    ttk::style configure $style -tabmargins     {2 2 1 0}
	    ttk::style map $style.Tab -expand {selected {2 2 1 0}}
	}
	s {
	    ttk::style configure $style -tabmargins     {2 0 1 2}
	    ttk::style map $style.Tab -expand {selected {2 0 1 2}}
	}
	w {
	    ttk::style configure $style -tabmargins     {2 2 0 1}
	    ttk::style map $style.Tab -expand {selected {2 2 0 1}}
	}
	e {
	    ttk::style configure $style -tabmargins     {0 2 2 1}
	    ttk::style map $style.Tab -expand {selected {0 2 2 1}}
	}
	default {
	    ttk::style configure $style -tabmargins     {2 2 1 0}
	    ttk::style map $style.Tab -expand {selected {2 2 1 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
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20













-







#
# 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 {
31
32
33
34
35
36
37






38
39
40
41
42
43
44
45






46
47


48
49






50
51
52








53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


57
58
59
60
61
62
63
64
65
66



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91


































92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118







+
+
+
+
+
+








+
+
+
+
+
+
-
-
+
+


+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+

















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-















-
+











	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

	# For Entry, Combobox and Spinbox widgets the selected text background
	# is the "Highlight color" selected in preferences when the widget
	# has focus.  It is a gray color when the widget does not have focus or
	# the window does not have focus. (The background state implies !focus
	# so we only need to specify !focus.)

	# Entry
	ttk::style configure TEntry \
	    -foreground systemTextColor \
	    -background systemTextBackgroundColor
	ttk::style map TEntry \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectbackground {
		!focus systemUnemphasizedSelectedTextBackgroundColor
	    }

	# Combobox:
	ttk::style map TCombobox \
	    -selectforeground {
		background systemTextColor
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectbackground {
		!focus systemUnemphasizedSelectedTextBackgroundColor
	    }

	# Spinbox
	ttk::style configure TSpinbox \
	    -foreground systemTextColor \
		background systemTextBackgroundColor
	    }

	    -background systemTextBackgroundColor
	ttk::style map TSpinbox \
	    -foreground {
		disabled systemDisabledControlTextColor
	    } \
	    -selectbackground {
		!focus systemUnemphasizedSelectedTextBackgroundColor
	    }

	# 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
	ttk::style configure TProgressbar -period 100 -maxphase 120

	# 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)
	#
	ttk::style configure TLabelframe \
		-labeloutside true -labelmargins {14 0 14 4}

	# TODO: panedwindow sashes should be 9 pixels (HIG:Controls:Split Views)
    }
}
Changes to library/ttk/clamTheme.tcl.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15







+







#
# "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"
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45


46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77

78
79

80
81

82
83
84
85




86
87
88
89
90







91
92
93




94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113


114
115
116
117
118
119
120


121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137


138
139
140
141
142
143
144
145
146
147































29
30
31
32
33
34
35


36

37
38
39
40
41
42


43
44
45
46
47
48
49
50
51
52
53
54
55

56

57
58
59
60
61
62
63
64
65
66
67
68
69
70

71

72
73
74
75
76

77
78
79
80
81



82
83
84
85





86
87
88
89
90
91
92



93
94
95
96
97
98
99
100
101
102
103
104

105


106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121

122
123
124
125
126
127
128

129

130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181







-
-
+
-






-
-
+
+











-
+
-














-
+
-



+

-
+


+

-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
+








-
+
-
-








-
+
+






-
+
+





-
+
-









-
+
+










+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
	    -foreground black \
	    -bordercolor $colors(-darkest) \
	    -darkcolor $colors(-dark) \
	    -lightcolor $colors(-lighter) \
	    -troughcolor $colors(-darker) \
	    -selectbackground $colors(-selectbg) \
	    -selectforeground $colors(-selectfg) \
	    -selectborderwidth 0 \
	    -font TkDefaultFont \
	    -font TkDefaultFont
	    ;

	ttk::style map "." \
	    -background [list disabled $colors(-frame) \
			     active $colors(-lighter)] \
	    -foreground [list disabled $colors(-disabledfg)] \
	    -selectbackground [list  !focus $colors(-darkest)] \
	    -selectforeground [list  !focus white] \
	    ;
	    -selectforeground [list  !focus white]

	# -selectbackground [list  !focus "#847d73"]

	ttk::style configure TButton \
	    -anchor center -width -11 -padding 5 -relief raised
	ttk::style map TButton \
	    -background [list \
			     disabled $colors(-frame) \
			     pressed $colors(-darker) \
			     active $colors(-lighter)] \
	    -lightcolor [list pressed $colors(-darker)] \
	    -darkcolor [list pressed $colors(-darker)] \
	    -bordercolor [list alternate "#000000"] \
	    -bordercolor [list alternate "#000000"]
	    ;

	ttk::style configure Toolbutton \
	    -anchor center -padding 2 -relief flat
	ttk::style map Toolbutton \
	    -relief [list \
		    disabled flat \
		    selected sunken \
		    pressed sunken \
		    active raised] \
	    -background [list \
		    disabled $colors(-frame) \
		    pressed $colors(-darker) \
		    active $colors(-lighter)] \
	    -lightcolor [list pressed $colors(-darker)] \
	    -darkcolor [list pressed $colors(-darker)] \
	    -darkcolor [list pressed $colors(-darker)]
	    ;

	ttk::style configure TCheckbutton \
	    -indicatorbackground "#ffffff" \
	    -indicatorforeground "#000000" \
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	    -padding 2
	ttk::style configure TRadiobutton \
	    -indicatorbackground "#ffffff" \
	    -indicatorforeground "#000000" \
	    -indicatormargin {1 1 4 1} \
	    -padding 2 ;
	ttk::style map TCheckbutton -indicatorbackground \
	    [list  pressed $colors(-frame) \
	    -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) \
		    {alternate disabled}  $colors(-disabledaltindicator) \
		    alternate		  $colors(-altindicator) \
		    disabled		  $colors(-frame)] \
	    -indicatorforeground [list disabled $colors(-disabledfg)]
	ttk::style map TRadiobutton \
	    -indicatorbackground [list \
		    pressed		  $colors(-frame) \
			{!disabled alternate} $colors(-altindicator) \
			{disabled alternate} $colors(-disabledaltindicator) \
			disabled $colors(-frame)]
		    {alternate disabled}  $colors(-disabledaltindicator) \
		    alternate		  $colors(-altindicator) \
		    disabled		  $colors(-frame)] \
	    -indicatorforeground [list disabled $colors(-disabledfg)]

	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"] \
	    -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)]
	    -arrowcolor [list disabled $colors(-disabledfg)] \
	    -bordercolor [list focus $colors(-selectbg)]
	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)]
            -arrowcolor [list disabled $colors(-disabledfg)] \
	    -bordercolor [list focus $colors(-selectbg)]

	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)] \
	    -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)]
				selected $colors(-selectfg)] \
	    -bordercolor [list focus $colors(-selectbg)]

    	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
    }
}

# ttk::theme::clam::configureNotebookStyle --
#
# Sets theme-specific option values for the ttk::notebook tab style $style.Tab.
# Invoked by ::ttk::configureNotebookStyle.

proc ttk::theme::clam::configureNotebookStyle {style} {
    set tabPos [ttk::style lookup $style -tabposition {} nw]
    switch -- [string index $tabPos 0] {
	n {
	    ttk::style configure $style.Tab -padding     {6 2 6 2}
	    ttk::style map $style.Tab -padding {selected {6 4 6 2}}
	}
	s {
	    ttk::style configure $style.Tab -padding     {6 2 6 2}
	    ttk::style map $style.Tab -padding {selected {6 2 6 4}}
	}
	w {
	    ttk::style configure $style.Tab -padding     {2 6 2 6}
	    ttk::style map $style.Tab -padding {selected {4 6 2 6}}
	}
	e {
	    ttk::style configure $style.Tab -padding     {2 6 2 6}
	    ttk::style map $style.Tab -padding {selected {2 6 4 6}}
	}
	default {
	    ttk::style configure $style.Tab -padding     {6 2 6 2}
	    ttk::style map $style.Tab -padding {selected {6 4 6 2}}
	}
    }
}
Changes to library/ttk/classicTheme.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
1
2
3
4
5
6
7
8

9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34

35
36
37
38
39
40
41
42








-
+
+



-
+


















-
+

-
+







#
# "classic" Tk theme.
#
# Implements Tk's traditional Motif-like look and feel.
#

namespace eval ttk::theme::classic {

    variable colors; array set colors {
    variable colors
    array set colors {
	-frame		"#d9d9d9"
	-window		"#ffffff"
	-activebg	"#ececec"
	-troughbg	"#c3c3c3"
	-troughbg	"#b3b3b3"
	-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 \
	    -selectbackground	$colors(-selectbg) \
	    -selectforeground	$colors(-selectfg) \
	    -troughcolor	$colors(-troughbg) \
	    -indicatorcolor	$colors(-frame) \
	    -highlightcolor	$colors(-frame) \
	    -highlightthickness	1 \
	    -selectborderwidth	1 \
	    -borderwidth	1 \
	    -insertwidth	2 \
	    ;
	    -focuswidth		0

	# To match pre-Xft X11 appearance, use:
	#	ttk::style configure . -font {Helvetica 12 bold}

	ttk::style map "." -background \
	    [list disabled $colors(-frame) active $colors(-activebg)]
	ttk::style map "." -foreground \
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66


67
68


69
70
71
72


73

74
75
76
77
78


79
80
81
82
83
84
85

86
87
88

89
90
91
92
93
94


95
96
97
98
99
100
101
102
103
104
105
106
107
108









109


110
111
112
113
114
115
50
51
52
53
54
55
56

57

58
59
60
61
62
63
64


65
66


67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91

92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
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::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} \
	    -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} \
	    ;
	    -indicatorrelief {alternate raised  selected sunken  pressed sunken}


	ttk::style configure TMenubutton -relief raised -padding "3m 1m"
	ttk::style configure TMenubutton -relief raised \
	    -indicatorborderwidth 2 -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)]

	ttk::style element create Combobox.downarrow from default
	ttk::style configure TCombobox -padding 1
	ttk::style configure TCombobox -padding 1 -arrowsize 12
	ttk::style map TCombobox -fieldbackground \
		[list readonly $colors(-frame) disabled $colors(-frame)]
	ttk::style configure ComboboxPopdownFrame \
	    -relief solid -borderwidth 1

	ttk::style element create Spinbox.uparrow from default
	ttk::style element create Spinbox.downarrow from default
	ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0}
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TLabelframe -borderwidth 2 -relief groove

	ttk::style configure TScrollbar -relief raised
	ttk::style configure TScrollbar -relief raised -arrowsize 12 -width 12
	ttk::style map TScrollbar -relief {{pressed !disabled} sunken}

	ttk::style configure TScale -sliderrelief raised
	ttk::style configure TScale -sliderrelief raised -sliderborderwidth 2
	ttk::style map TScale -sliderrelief {{pressed !disabled} sunken}

	ttk::style configure TProgressbar -background SteelBlue
	ttk::style configure TNotebook.Tab \
	    -padding {3m 1m} \
	    -background $colors(-troughbg)
	    -background $colors(-troughbg) \
	    -focussolid 1
	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 layout Toolbutton {
	    Toolbutton.focus -children {
		Toolbutton.border -children {
		    Toolbutton.padding -children {
			Toolbutton.label
		    }
		}
	    }
	}
	ttk::style configure Toolbutton -padding 2 -relief flat -shiftrelief 2
	ttk::style configure Toolbutton -padding 2 -relief flat \
	    -shiftrelief 2 -focussolid 1
	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.
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221

222
223
224
225
226
227
228
178
179
180
181
182
183
184

185
186
187
188





189
190
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216

217
218
219
220
221
222
223
224







-
+



-
-
-
-
-
+










-
+









-
+






-
+







    $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}} {
proc ttk::combobox::Scroll {cb dir} {
    $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
    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 [LBMain $lb]
    set cb [LBMaster $lb]
    LBSelect $lb
    Unpost $cb
    focus $cb
}

## LBCancel --
#	Unpost the listbox.
#
proc ttk::combobox::LBCancel {lb} {
    Unpost [LBMain $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 [LBMain $lb]
    set cb [LBMaster $lb]
    switch -- $dir {
	next	{ set newFocus [tk_focusNext $cb] }
	prev	{ set newFocus [tk_focusPrev $cb] }
    }

    if {$newFocus ne ""} {
	LBSelect $lb
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
265
266
267
268
269
270
271

272

273
274
275
276
277
278
279







-
+
-







	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 \
	    -activestyle none
	    ;

	bindtags $popdown.l \
	    [list $popdown.l ComboboxListbox Listbox $popdown all]

	grid $popdown.l -row 0 -column 0 -padx {1 0} -pady 1 -sticky nsew
        grid $popdown.sb -row 0 -column 1 -padx {0 1} -pady 1 -sticky ns
	grid columnconfigure $popdown 0 -weight 1
414
415
416
417
418
419
420
421

422
423
424

425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
409
410
411
412
413
414
415

416
417
418

419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447







-
+


-
+







-
+
















-
+



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 --
## LBMaster $lb --
#	Return the combobox main widget that owns the listbox.
#
proc ttk::combobox::LBMain {lb} {
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 [LBMain $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([LBMain $lb])
    unset Values([LBMaster $lb])
}

#*EOF*
Changes to library/ttk/defaults.tcl.
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
24
25
26
27
28
29
30

31
32
33

34

35
36
37
38
39
40
41







-



-
+
-








	ttk::style configure "." \
	    -borderwidth 	1 \
	    -background 	$colors(-frame) \
	    -foreground 	$colors(-foreground) \
	    -troughcolor 	$colors(-darker) \
	    -font 		TkDefaultFont \
	    -selectborderwidth	1 \
	    -selectbackground	$colors(-selectbg) \
	    -selectforeground	$colors(-selectfg) \
	    -insertwidth 	1 \
	    -indicatordiameter	10 \
	    -indicatordiameter	10
	    ;

	ttk::style map "." -background \
	    [list disabled $colors(-frame)  active $colors(-activebg)]
	ttk::style map "." -foreground \
	    [list disabled $colors(-disabledfg)]

	ttk::style configure TButton \
64
65
66
67
68
69
70
71

72
73
74


75
76
77
78




79
80
81
82
83




84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104



105
106
107
108
109
110
111


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131



132
133
134
135
136
137
138
139
140
141
142
143
62
63
64
65
66
67
68

69
70
71

72
73
74
75
76

77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138


139
140
141
142
143
144

145
146
147
148
149
150
151
152







-
+


-
+
+



-
+
+
+
+




-
+
+
+
+













-
+






-
+
+
+






-
+
+


















+
-
-
+
+
+



-








			{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"
	    -relief raised -indicatorborderwidth 1 -padding "10 3"

	ttk::style configure TEntry \
	    -relief sunken -fieldbackground white -padding 1
	    -fieldbackground white -padding 1 \
	    -focuswidth 2 -focuscolor $colors(-selectbg)
	ttk::style map TEntry -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)]

	ttk::style configure TCombobox -arrowsize 12 -padding 1
	ttk::style configure TCombobox \
	    -arrowsize 12 -arrowcolor black \
	    -fieldbackground white -padding 1 \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	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 configure TSpinbox \
	    -arrowsize 10 -arrowcolor black \
	    -fieldbackground white -padding {2 0 10 0} \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	ttk::style map TSpinbox -fieldbackground \
	    [list readonly $colors(-frame) disabled $colors(-frame)] \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TLabelframe \
	    -relief groove -borderwidth 2

	ttk::style configure TScrollbar \
	    -width 12 -arrowsize 12
	ttk::style map TScrollbar \
	    -arrowcolor [list disabled $colors(-disabledfg)]

	ttk::style configure TScale \
	    -sliderrelief raised
	    -sliderrelief raised -sliderborderwidth 1
	ttk::style configure TProgressbar \
	    -background $colors(-selectbg)

	ttk::style configure TNotebook.Tab \
	    -padding {4 2} -background $colors(-darker)
	ttk::style map TNotebook.Tab \
	    -background [list selected $colors(-frame)]
	    -background [list selected $colors(-frame)] \
	    -highlight [list selected 1] \
	    -highlightcolor [list selected $colors(-selectbg)]

	# Treeview.
	#
	ttk::style configure Heading -font TkHeadingFont -relief raised
	ttk::style configure Treeview \
	    -background $colors(-window) \
	    -foreground $colors(-text) ;
	    -foreground $colors(-text) \
	    -focuswidth 1 -focuscolor $colors(-selectbg)
	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

	#
	# Toolbar buttons:
	#
	ttk::style layout Toolbutton {
	    Toolbutton.border -children {
		Toolbutton.focus -children {
		Toolbutton.padding -children {
		    Toolbutton.label
		    Toolbutton.padding -children {
			Toolbutton.label
		    }
		}
	    }
	}

	ttk::style configure Toolbutton \
	    -padding 2 -relief flat
	ttk::style map Toolbutton -relief \
	    [list disabled flat selected sunken pressed sunken active raised]
	ttk::style map Toolbutton -background \
	    [list pressed $colors(-darker)  active $colors(-activebg)]
    }
}
Changes to library/ttk/entry.tcl.
1
2
3
4
5
6



7
8
9
10
11
12
13
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
# 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 {
78
79
80
81
82
83
84
85

86
87

88
89

90
91
92








93
94
95
96
97
98
99
78
79
80
81
82
83
84

85
86

87
88
89
90



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







-
+

-
+


+
-
-
-
+
+
+
+
+
+
+
+







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:
## Button2 (Button3 on Aqua) bindings:
#	Used for scanning and primary transfer.
#	Note: ButtonRelease-2
#	Note: ButtonRelease-2 (ButtonRelease-3 on Aqua)
#	is mapped to <<PasteSelection>> in tk.tcl.
#
if {[tk windowingsystem] ne "aqua"} {
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 <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 }
} else {
    bind TEntry <Button-3> 		{ ttk::entry::ScanMark %W %x }
    bind TEntry <B3-Motion> 		{ ttk::entry::ScanDrag %W %x }
    bind TEntry <ButtonRelease-3>	{ 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 }
131
132
133
134
135
136
137

138
139
140
141
142
143
144
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151







+







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}
    bind TEntry <Mod4-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:
#
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190







-
+







#

## 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]
	    [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
}

243
244
245
246
247
248
249




250
251
252
253
254
255
256
257
258
259
260
261
262
263




264
265
266
267
268
269
270
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285







+
+
+
+














+
+
+
+







#	either the next end-of-word position, or the start-of-word
#	position following the next end-of-word position.
#
set ::ttk::entry::State(startNext) \
	[string equal [tk windowingsystem] "win32"]

proc ttk::entry::NextWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return end
    }
    variable State
    set pos [tcl_endOfWord [$w get] [$w index $start]]
    if {$pos >= 0 && $State(startNext)} {
	set pos [tcl_startOfNextWord [$w get] $pos]
    }
    if {$pos < 0} {
	return end
    }
    return $pos
}

## PrevWord -- Find the previous word position.
#
proc ttk::entry::PrevWord {w start} {
    # the check on [winfo class] is because the spinbox and combobox also use this proc
    if {[winfo class $w] eq "TEntry" && [$w cget -show] ne ""} {
	return 0
    }
    set pos [tcl_startOfPreviousWord [$w get] [$w index $start]]
    if {$pos < 0} {
	return 0
    }
    return $pos
}

Changes to library/ttk/fonts.tcl.
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55




56
57
58
59
60
61
62
41
42
43
44
45
46
47



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63







-
-
-





+
+
+
+







#
#	Note that the font for column headings (TkHeadingFont) is
#	_smaller_ than the default font.
#
#	There does not appear to be any recommendations for fixed-width fonts.
#
# X11:
#	Need a way to tell if Xft is enabled or not.
#	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}
123
124
125
126
127
128
129
130
131
132
133




134
135
136
137
138
139
140
124
125
126
127
128
129
130




131
132
133
134
135
136
137
138
139
140
141







-
-
-
-
+
+
+
+







	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
	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.
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
78
79
80
81
82
83
84


85

86
87
88
89
90
91
92
93







-
-

-
+







	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 ""} {
	if {$entry < 0} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry ""
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136

137
138
139
140
141

142
143
144
145

146
147
148
149

150
151
152
153
154
155
156
157
158
159

160
161

162
163
164
165
166
167
168
169
170
171
172
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123

124

125
126
127
128
129
130
131

132
133
134
135
136

137
138
139
140

141
142
143
144

145

146
147
148
149
150
151
152
153

154


155




156
157
158
159
160
161
162







-
+











-




-

-
+






-
+




-
+



-
+



-
+
-








-
+
-
-
+
-
-
-
-







		incr y $menuPad
		incr x -$mw
	    }
	    right {
		incr y $menuPad
		incr x $bw
	    }
	    default {
	    default {  # flush
		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 {}} {
	if {$entry < 0} {
	    set entry 0
	}
	set x [winfo rootx $mb]
	set y [winfo rooty $mb]
	switch [$mb cget -direction] {
	    above {
		set entry {}
		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]}]
			    + [winfo reqheight $mb]}]
		}
	    }
	    below {
		set entry {}
		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] \
		    set y [expr {[winfo vrooty $mb] + [winfo rooty $mb] - $mh}]
			   + [winfo rooty $mb] - $mh}]
		}
	    }
	    left {
		incr x -$mw
	    }
	    right {
		incr x $bw
	    }
	    default {
	    default {  # flush
		if {[$mb cget -style] eq ""} {
		    incr x [expr {([winfo width $mb] - \
		incr x [expr {([winfo width $mb] - [winfo reqwidth $menu])/ 2}]
				   [winfo reqwidth $menu])/ 2}]
		} else {
		    incr y $bh
		}
	    }
	}
	return [list $x $y $entry]
    }
}

# Popdown --
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196







-
+







    }
    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 {}} {
    if {$entry >= 0} {
	$menu post $x $y $entry
    } else {
	$menu post $x $y
    }
    tk_menuSetFocus $menu
}

224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233







-
+












# 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 ""} {
    if {$last eq "none" || $last < 0} {
	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.
53
54
55
56
57
58
59
60
61
62
63
64







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84




85
86
87
88
89
90
91
53
54
55
56
57
58
59





60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84



85
86
87
88
89
90
91
92
93
94
95







-
-
-
-
-
+
+
+
+
+
+
+

















+
-
-
-
+
+
+
+







    }
}

# CycleTab --
#	Select the next/previous tab in the list.
#
proc ttk::notebook::CycleTab {w dir} {
    if {[$w index end] != 0} {
	set current [$w index current]
	set select [expr {($current + $dir) % [$w index end]}]
	while {[$w tab $select -state] != "normal" && ($select != $current)} {
	    set select [expr {($select + $dir) % [$w index end]}]
    set current [$w index current]
    if {$current >= 0} {
	set tabCount [$w index end]
	set select [expr {($current + $dir) % $tabCount}]
	set step [expr {$dir > 0 ? 1 : -1}]
	while {[$w tab $select -state] ne "normal" && ($select != $current)} {
	    set select [expr {($select + $step) % $tabCount}]
	}
	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]
	set underline [$nb tab $tab -underline]
	if {$underline >= 0} {
	set mnemonic [string toupper [string index $label $underline]]
	if {$mnemonic ne "" && $mnemonic eq $key} {
	    return $tab
	    set mnemonic [string toupper [string index $label $underline]]
	    if {$mnemonic ne "" && $mnemonic eq $key} {
		return $tab
	    }
	}
    }
    return ""
}

# +++ Toplevel keyboard traversal.
#
Changes to library/ttk/panedwindow.tcl.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
18
19
20
21
22
23
24


25
26
27
28
29
30
31







-
-







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>>
bind TPanedwindow <<EnteredChild>>	{ ttk::panedwindow::ResetCursor %W }

## Sash movement:
#
proc ttk::panedwindow::Press {w x y} {
    variable State

    set sash [$w identify $x $y]
41
42
43
44
45
46
47
48
49
50



51
52
53
54
55
56
57
39
40
41
42
43
44
45



46
47
48
49
50
51
52
53
54
55







-
-
-
+
+
+







    set State(sash) 	$sash
    set State(sashPos)	[$w sashpos $sash]
}

proc ttk::panedwindow::Drag {w x y} {
    variable State
    if {!$State(pressed)} { return }
    switch -- [$w cget -orient] {
    	horizontal 	{ set delta [expr {$x - $State(pressX)}] }
    	vertical 	{ set delta [expr {$y - $State(pressY)}] }
    switch -glob -- [$w cget -orient] {
    	h*  { set delta [expr {$x - $State(pressX)}] }
    	v*  { set delta [expr {$y - $State(pressY)}] }
    }
    $w sashpos $State(sash) [expr {$State(sashPos) + $delta}]
}

proc ttk::panedwindow::Release {w x y} {
    variable State
    set State(pressed) 0
76
77
78
79
80
81
82
83
84
85



86
87
88
89
90
91
74
75
76
77
78
79
80



81
82
83
84
85
86
87
88
89







-
-
-
+
+
+







    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 }
	switch -glob -- [$w cget -orient] {
	    h*  { set cursor hresize }
	    v*  { set cursor vresize }
	}
    }
    ttk::setCursor $w $cursor
}

#*EOF*
Changes to library/ttk/scrollbar.tcl.
15
16
17
18
19
20
21


22
23














24
25
26
27
28
29
30
15
16
17
18
19
20
21
22
23


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44







+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+








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
#
# The shift-bindings scroll left/right (not up/down)
# if a widget has both possibilities
bind TScrollbar <MouseWheel> [bind Scrollbar <MouseWheel>]
bind TScrollbar <Option-MouseWheel> [bind Scrollbar <Option-MouseWheel>]
set eventList [list <MouseWheel> <Shift-MouseWheel>]
switch [tk windowingsystem] {
    aqua {
        lappend eventList <Option-MouseWheel> <Shift-Option-MouseWheel>
    }
    x11 {
        lappend eventList <Button-4> <Button-5> \
                <Shift-Button-4> <Shift-Button-5>
    }
}
foreach event $eventList {
    bind TScrollbar $event [bind Scrollbar $event]
}
unset eventList event

proc ttk::scrollbar::Scroll {w n units} {
    set cmd [$w cget -command]
    if {$cmd ne ""} {
	uplevel #0 $cmd scroll $n $units
    }
}
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100







-
+







}

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;
	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} {
Changes to library/ttk/sizegrip.tcl.
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64







-
+







    }

    # Sanity-checks:
    #	If a negative X or Y position was specified for [wm geometry],
    #   just bail out -- there's no way to handle this cleanly.
    #
    if {[scan [wm geometry $top] "%dx%d+%d+%d" width height x y] != 4} {
	return;
	return
    }

    # Account for gridded geometry:
    #
    set grid [wm grid $top]
    if {[llength $grid]} {
	set State(widthInc) [lindex $grid 2]
Changes to library/ttk/spinbox.tcl.
78
79
80
81
82
83
84
85

86
87

88
89

90
91
92
93
94
95
96
78
79
80
81
82
83
84

85
86

87
88

89
90
91
92
93
94
95
96







-
+

-
+

-
+







    ttk::CancelRepeat
}

## MouseWheel --
#	Mousewheel callback.  Turn these into <<Increment>> (-1, up)
# 	or <<Decrement> (+1, down) events.
#
proc ttk::spinbox::MouseWheel {w dir {factor 1}} {
proc ttk::spinbox::MouseWheel {w dir} {
    if {[$w instate disabled]} { return }
    if {($dir < 0) ^ ($factor < 0)} {
    if {$dir < 0} {
	event generate $w <<Increment>>
    } elseif {$dir > 0} {
    } else {
	event generate $w <<Decrement>>
    }
}

## SelectAll --
#	Select widget contents.
#
Changes to library/ttk/ttk.tcl.
90
91
92
93
94
95
96















97
98
99
100
101
102
103
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    variable currentTheme ;# @@@ Temp -- [::ttk::style theme use] doesn't work
    if {$theme ni [::ttk::style theme names]} {
	package require ttk::theme::$theme
    }
    ::ttk::style theme use $theme
    set currentTheme $theme
}

## ttk::configureNotebookStyle $style --
#	Sets theme-specific option values for the ttk::notebook style $style
#	and/or the style $style.Tab.  To be invoked if the -tabposition option
#	of $style has a non-default value (like "sw", "wn", or "en").
#
proc ::ttk::configureNotebookStyle {style} {
    set theme [ttk::style theme use]
    if {[llength [info procs theme::${theme}::configureNotebookStyle]] > 0} {
	theme::${theme}::configureNotebookStyle $style
	return 1
    } else {
	return 0
    }
}

### 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]
Changes to library/ttk/utils.tcl.
33
34
35
36
37
38
39
40

41
42
43
44
45

46
47
48
49
50
51
52
33
34
35
36
37
38
39

40
41
42
43
44

45
46
47
48
49
50
51
52







-
+




-
+







    if {![catch {$w cget -state} state] && $state eq "disabled"} {
	return 0
    }

    # Allow traversal to widgets with explicit key or focus bindings:
    #
    if {[regexp {Key|Focus} [concat [bind $w] [bind [winfo class $w]]]]} {
	return 1;
	return 1
    }

    # Default is nontraversable:
    #
    return 0;
    return 0
}

## ttk::traverseTo $w --
# 	Set the keyboard focus to the specified window.
#
proc ttk::traverseTo {w} {
    set focus [focus]
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178







-
+







#	If called more than once without an intervening [SaveGrab $w],
#	does nothing.
#
proc ttk::RestoreGrab {w} {
    variable Grab

    if {![info exists Grab($w)]} {	# Ignore
	return;
	return
    }

    # The previous grab/focus window may have been destroyed,
    # unmapped, or some other abnormal condition; ignore any errors.
    #
    foreach script $Grab($w) {
	catch $script
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
255
256







-

+







-

+







#	Begin auto-repeat.
#
proc ttk::Repeatedly {args} {
    variable Repeat
    after cancel $Repeat(timer)
    set script [uplevel 1 [list namespace code $args]]
    set Repeat(script) $script
    uplevel #0 $script
    set Repeat(timer) [after $Repeat(delay) ttk::Repeat]
    uplevel #0 $script
}

## Repeat --
#	Continue auto-repeat
#
proc ttk::Repeat {} {
    variable Repeat
    uplevel #0 $Repeat(script)
    set Repeat(timer) [after $Repeat(interval) ttk::Repeat]
    uplevel #0 $Repeat(script)
}

## ttk::CancelRepeat --
#	Halt auto-repeat.
#
proc ttk::CancelRepeat {} {
    variable Repeat
268
269
270
271
272
273
274












275
276
277
278
279
280
281
282
283
284
285
286
287





288
289
290
291






292
293
294


295
296
297
298
299
300
301
302
303
304
305
306
307
308























309
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304




305
306
307
308
309
310



311
312
313













314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337







+
+
+
+
+
+
+
+
+
+
+
+













+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

	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.
#
# 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} {
    if {[tk windowingsystem] eq "x11"} {
	bind $bindtag <Button-4> "$callback -1"
	bind $bindtag <Button-5> "$callback +1"
    }
    if {[tk windowingsystem] eq "aqua"} {
    bind $bindtag <MouseWheel> [append callback { %D -120.0}]
    bind $bindtag <Option-MouseWheel> [append callback { %D -12.0}]
}

	bind $bindtag <MouseWheel> "$callback \[expr {-%D}\]"
	bind $bindtag <Option-MouseWheel> "$callback \[expr {-10 * %D}\]"
    } else {
	bind $bindtag <MouseWheel> "$callback \[expr {-%D / 120}\]"
    }
}
## Mousewheel bindings for standard scrollable widgets.
#
# Usage: [ttk::copyBindings TtkScrollable $bindtag]

## Mousewheel bindings for standard scrollable widgets.
#
# $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 }


if {[tk windowingsystem] eq "x11"} {
    bind TtkScrollable <Button-4>       { %W yview scroll -5 units }
    bind TtkScrollable <Button-5>       { %W yview scroll  5 units }
    bind TtkScrollable <Shift-Button-4> { %W xview scroll -5 units }
    bind TtkScrollable <Shift-Button-5> { %W xview scroll  5 units }
}
if {[tk windowingsystem] eq "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 }
} else {
    bind TtkScrollable <MouseWheel> \
	    { %W yview scroll [expr {-%D / 120}] units }
    bind TtkScrollable <Shift-MouseWheel> \
	    { %W xview scroll [expr {-%D / 120}] units }
}

#*EOF*
Changes to library/ttk/vistaTheme.tcl.
18
19
20
21
22
23
24
25
26


27
28
29

30
31
32
33
34
35
36
37
18
19
20
21
22
23
24


25
26

27

28

29
30
31
32
33
34
35







-
-
+
+
-

-
+
-








 	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;
	    -font TkDefaultFont


	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    -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 element create Menubutton.dropdown vsapi \
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
124
87
88
89
90
91
92
93

94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113

114
115
116
117
118
119
120







-
+
-


















-
+
-







	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -foreground	[list \
		disabled		SystemGrayText \
	    	{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight] \
	    -focusfill	[list {readonly focus} SystemHighlight]
	    ;

        # Entry
        ttk::style configure TEntry -padding {1 1 1 1} ;# Needs lookup
        ttk::style element create Entry.field vsapi \
            EDIT 6 {disabled 4 focus 3 hover 2 {} 1} -padding {2 2 2 2}
        ttk::style element create Entry.background vsapi \
            EDIT 3 {disabled 3 readonly 3 focus 4 hover 2 {} 1}
        ttk::style layout TEntry {
            Entry.field -sticky news -border 0 -children {
                Entry.background -sticky news -children {
                    Entry.padding -sticky news -children {
                        Entry.textarea -sticky news
                    }
                }
            }
        }
	ttk::style map TEntry \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -selectforeground [list !focus SystemWindowText]
	    ;

        # Spinbox
        ttk::style configure TSpinbox -padding 0
        ttk::style element create Spinbox.field vsapi \
            EDIT 9 {disabled 4 focus 3 hover 2 {} 1} -padding {1 1 1 2}
        ttk::style element create Spinbox.background vsapi \
            EDIT 3 {disabled 3 readonly 3 focus 4 hover 2 {} 1}
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
140
141
142
143
144
145
146

147

148
149
150
151
152
153
154







-
+
-







                    Spinbox.uparrow -side top -sticky ens
                    Spinbox.downarrow -side bottom -sticky ens
                }
            }
        }
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -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 \
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
178
179
180
181
182
183
184

185
186
187
188
189
190
191







-








        # 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
224
225
226
227
228
229
230































218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

        # Treeview
        ttk::style configure Item -padding {4 0 0 0}

        package provide ttk::theme::vista 1.0
    }
}

# ttk::theme::vista::configureNotebookStyle --
#
# Sets theme-specific option values for the ttk::notebook style $style and the
# style $style.Tab.  Invoked by ::ttk::configureNotebookStyle.

proc ttk::theme::vista::configureNotebookStyle {style} {
    set tabPos [ttk::style lookup $style -tabposition {} nw]
    switch -- [string index $tabPos 0] {
	n {
	    ttk::style configure $style -tabmargins     {2 2 2 0}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	s {
	    ttk::style configure $style -tabmargins     {2 0 2 2}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	w {
	    ttk::style configure $style -tabmargins     {2 2 0 2}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	e {
	    ttk::style configure $style -tabmargins     {0 2 2 2}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	default {
	    ttk::style configure $style -tabmargins     {2 2 2 0}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
    }
}
Changes to library/ttk/winTheme.tcl.
9
10
11
12
13
14
15
16
17


18
19
20


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

33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
9
10
11
12
13
14
15


16
17



18
19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35

36

37
38
39
40
41
42
43
44
45
46
47
48

49

50
51
52
53
54
55
56







-
-
+
+
-
-
-
+
+











-
+




-
+
-












-
+
-







	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -fieldbackground SystemWindow \
	    -insertcolor SystemWindowText \
	    -troughcolor SystemScrollbar \
	    -font TkDefaultFont \
	    ;
	    -font TkDefaultFont


	ttk::style map "." -foreground [list disabled SystemGrayText] ;
        ttk::style map "." -embossed [list disabled 1] ;
	ttk::style map "." -foreground [list disabled SystemGrayText]
        ttk::style map "." -embossed [list disabled 1]

	ttk::style configure TButton \
	    -anchor center -width -11 -relief raised -shiftrelief 1
	ttk::style configure TCheckbutton -padding "2 4"
	ttk::style configure TRadiobutton -padding "2 4"
	ttk::style configure TMenubutton \
	    -padding "8 4" -arrowsize 3 -relief raised

	ttk::style map TButton -relief {{!disabled pressed} sunken}

	ttk::style configure TEntry \
	    -padding 2 -selectborderwidth 0 -insertwidth 1
	    -padding 2 -insertwidth 1
	ttk::style map TEntry \
	    -fieldbackground \
	    	[list readonly SystemButtonFace disabled SystemButtonFace] \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -selectforeground [list !focus SystemWindowText]
	    ;

	ttk::style configure TCombobox -padding 2
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -fieldbackground [list \
	    	readonly SystemButtonFace \
		disabled SystemButtonFace] \
	    -foreground	[list \
		disabled		SystemGrayText \
	    	{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight] \
	    -focusfill	[list {readonly focus} SystemHighlight]
	    ;

	ttk::style element create ComboboxPopdownFrame.border from default
	ttk::style configure ComboboxPopdownFrame \
	    -borderwidth 1 -relief solid

        ttk::style configure TSpinbox -padding {2 0 16 0}

75
76
77
78
79
80
81
82

83
84































72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112







-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
	ttk::style map Treeview \
	    -background [list   disabled SystemButtonFace \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				selected SystemHighlightText]

        ttk::style configure TProgressbar \
	    -background SystemHighlight -borderwidth 0 ;
	    -background SystemHighlight -borderwidth 0
    }
}

# ttk::theme::winnative::configureNotebookStyle --
#
# Sets theme-specific option values for the ttk::notebook style $style and the
# style $style.Tab.  Invoked by ::ttk::configureNotebookStyle.

proc ttk::theme::winnative::configureNotebookStyle {style} {
    set tabPos [ttk::style lookup $style -tabposition {} nw]
    switch -- [string index $tabPos 0] {
	n {
	    ttk::style configure $style -tabmargins     {2 2 2 0}
	    ttk::style map $style.Tab -expand {selected {2 2 2 0}}
	}
	s {
	    ttk::style configure $style -tabmargins     {2 0 2 2}
	    ttk::style map $style.Tab -expand {selected {2 0 2 2}}
	}
	w {
	    ttk::style configure $style -tabmargins     {2 2 0 2}
	    ttk::style map $style.Tab -expand {selected {2 2 0 2}}
	}
	e {
	    ttk::style configure $style -tabmargins     {0 2 2 2}
	    ttk::style map $style.Tab -expand {selected {0 2 2 2}}
	}
	default {
	    ttk::style configure $style -tabmargins     {2 2 2 0}
	    ttk::style map $style.Tab -expand {selected {2 2 2 0}}
	}
    }
}
Changes to library/ttk/xpTheme.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































8
9
10
11
12
13
14


15
16

17

18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

35

36
37
38
39
40
41
42
43

44

45
46
47
48

49

50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93







-
-
+
+
-

-
+
-
















-
+
-








-
+
-




-
+
-










-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;
	    -font TkDefaultFont


	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    -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] \
	    -selectforeground [list !focus SystemWindowText]
	    ;
	ttk::style configure TCombobox -padding 2
	ttk::style map TCombobox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -foreground	[list \
		disabled		SystemGrayText \
	    	{readonly focus}	SystemHighlightText \
	    ] \
	    -focusfill	[list {readonly focus} SystemHighlight] \
	    -focusfill	[list {readonly focus} SystemHighlight]
	    ;

	ttk::style configure TSpinbox -padding {2 0 14 0}
	ttk::style map TSpinbox \
	    -selectbackground [list !focus SystemWindow] \
	    -selectforeground [list !focus SystemWindowText] \
	    -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];
				selected SystemHighlightText]
    }
}

# ttk::theme::xpnative::configureNotebookStyle --
#
# Sets theme-specific option values for the ttk::notebook style $style and the
# style $style.Tab.  Invoked by ::ttk::configureNotebookStyle.

proc ttk::theme::xpnative::configureNotebookStyle {style} {
    set tabPos [ttk::style lookup $style -tabposition {} nw]
    switch -- [string index $tabPos 0] {
	n {
	    ttk::style configure $style -tabmargins     {2 2 2 0}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	s {
	    ttk::style configure $style -tabmargins     {2 0 2 2}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	w {
	    ttk::style configure $style -tabmargins     {2 2 0 2}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	e {
	    ttk::style configure $style -tabmargins     {0 2 2 2}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
	default {
	    ttk::style configure $style -tabmargins     {2 2 2 0}
	    ttk::style map $style.Tab -expand {selected {2 2 2 2}}
	}
    }
}
Changes to library/xmfbox.tcl.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
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
# 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 {}

79
80
81
82
83
84
85
86

87
88

89
90
91
92
93
94
95
79
80
81
82
83
84
85

86
87

88
89
90
91
92
93
94
95







-
+

-
+








proc ::tk::MotifFDialog_Create {dataName type argList} {
    upvar ::tk::dialog::file::$dataName data

    MotifFDialog_Config $dataName $type $argList

    if {$data(-parent) eq "."} {
        set w .$dataName
	set w .$dataName
    } else {
        set w $data(-parent).$dataName
	set w $data(-parent).$dataName
    }

    # (re)create the dialog box if necessary
    #
    if {![winfo exists $w]} {
	MotifFDialog_BuildUI $w
    } elseif {[winfo class $w] ne "TkMotifFDialog"} {
206
207
208
209
210
211
212

213
214
215
216
217
218
219
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
544
545
546
547
548
549
550
551

552
553
554
555
556
557
558
545
546
547
548
549
550
551

552
553
554
555
556
557
558
559







-
+







#	None.

proc ::tk::MotifFDialog_Update {w} {
    upvar ::tk::dialog::file::[winfo name $w] data

    $data(fEnt) delete 0 end
    $data(fEnt) insert 0 \
            [::tk::dialog::file::JoinFile $data(selectPath) $data(filter)]
	    [::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
}

592
593
594
595
596
597
598
599
600


601
602
603
604
605

606
607

608
609
610
611
612
613
614
593
594
595
596
597
598
599


600
601
602
603
604
605

606
607

608
609
610
611
612
613
614
615







-
-
+
+




-
+

-
+







    set top 0
    set dlist ""
    set flist ""
    foreach f [glob -nocomplain .* *] {
	if {[file isdir ./$f]} {
	    lappend dlist $f
	} else {
            foreach pat $data(filter) {
                if {[string match $pat $f]} {
	    foreach pat $data(filter) {
		if {[string match $pat $f]} {
		    if {[string match .* $f]} {
			incr top
		    }
		    lappend flist $f
                    break
		    break
		}
            }
	    }
	}
    }
    eval [list $data(dList) insert end] [lsort -dictionary $dlist]
    eval [list $data(fList) insert end] [lsort -dictionary $flist]

    # The user probably doesn't want to see the . files. We adjust the view
    # so that the listbox displays all the non-dot files
902
903
904
905
906
907
908
909

910
911

912
913
914
915
916
917
918
903
904
905
906
907
908
909

910
911

912
913
914
915
916
917
918
919







-
+

-
+








    set Priv(selectFilePath) ""
    set Priv(selectFile)     ""
    set Priv(selectPath)     ""
}

proc ::tk::ListBoxKeyAccel_Set {w} {
    bind Listbox <Key> ""
    bind Listbox <Any-Key> ""
    bind $w <Destroy> [list tk::ListBoxKeyAccel_Unset $w]
    bind $w <Key> [list tk::ListBoxKeyAccel_Key $w %A]
    bind $w <Any-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)
975
976
977
978
979
980
981
982






976
977
978
979
980
981
982
983
984
985
986
987
988
989








+
+
+
+
+
+
}

proc ::tk::ListBoxKeyAccel_Reset {w} {
    variable ::tk::Priv

    unset -nocomplain Priv(lbAccel,$w)
}

proc ::tk_getFileType {} {
    variable ::tk::Priv

    return $Priv(selectFileType)
}

Added macosx/Credits.html.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<!doctype htmL>
<html>
<head>
</head>
<body style="font-size:120%;font-family:Arial,sans-serif;">
<p>
Tcl and Tk are distributed under a modified BSD license:<br>
<a href="https://www.tcl-lang.org/software/tcltk/license.html">
  https://www.tcl-lang.org/software/tcltk/license.html
</a>
</p>
<ul style="list-style-type:none;">
<li>&copy; 1987-@TK_YEAR@ Tcl Core Team and Contributers.</li>
<li>&copy; 2011-@TK_YEAR@ Kevin Walzer/WordTech Communications LLC.</li>
<li>&copy; 2014-@TK_YEAR@ Marc Culler.</li>
<li>&copy; 2002-2012 Daniel A. Steffen.</li>
<li>&copy; 2001-2009 Apple Inc.</li>
<li>&copy; 2001-2002 Jim Ingham &amp; Ian Reid.</li>
<li>&copy; 1998-2000 Jim Ingham &amp; Ray Johnson.</li>
<li>&copy; 1998-2000 Scriptics Inc.</li>
<li>&copy; 1996-1997 Sun Microsystems Inc.</li>
</ul>
</body>
</html>
Changes to macosx/GNUmakefile.
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
42
43
44
45
46
47
48






49
50
51
52
53
54
55







-
-
-
-
-
-







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

111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119







-
+







#-------------------------------------------------------------------------------------------------------
# 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)
VERSION			:= $(shell awk -F= '/^TK_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.in)
TCL_VERSION		:= ${VERSION}
wish			:= wish
WISH			= wish${VERSION}

BUILD_TARGET		:= binaries libraries tktest
INSTALL_TARGET		:= install

141
142
143
144
145
146
147
148

149
150

151
152
153
154
155
156
157
135
136
137
138
139
140
141

142
143

144
145
146
147
148
149
150
151







-
+

-
+







else
override CONFIGURE_ARGS := ${CONFIGURE_ARGS} --enable-xft
VERSION			:= ${VERSION}-X11
wish			:= ${wish}-X11
override EMBEDDED_BUILD :=
endif

INSTALL_TARGETS		= install-binaries install-libraries
INSTALL_TARGETS		= install-binaries install-libraries install-headers
ifeq (${EMBEDDED_BUILD},)
INSTALL_TARGETS		+= install-private-headers install-headers install-demos
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
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197







-
+







	${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 \
	--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

Changes to macosx/README.
165
166
167
168
169
170
171
172

173
174
175
176
177

178
179
180
181
182
183
184
165
166
167
168
169
170
171

172
173
174
175
176

177
178
179
180
181
182
183
184







-
+




-
+







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.
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
  tk::unsupported::MacWindowStyle isdark window?
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.
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283

284
285
286
287
288
289
290
291
292












293
294
295
296
297
298
299
268
269
270
271
272
273
274




275





276









277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295







-
-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+







---------------------------------------

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 the following semantic colors as system colors:
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
systemTextColor, systemTextBackgroundColor, systemSelectedTextColor,
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.
systemSelectedTextBackgroundColor, systemControlTextColor,
systemDisabledControlTextColor, systemLabelColor, systemLinkColor, and
systemControlAccentColor.  All of these except the last three were
present in OSX 10.0 (and those three are simulated in systems where they
do not exist).  The change in 10.14 was that the RGB color value of
these colors became dynamic, meaning that the color value can change
when the application appearance changes.  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.  One additional color, systemSelectedTabTextColor, does not
exist in macOS but is used by Tk to match the different colors used
for Notebook tab text 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.

548
549
550
551
552
553
554
555

556
557
558
559
560
561
562
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558







-
+







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
sufficient for safe memory management 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
641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
637
638
639
640
641
642
643

644
645
646
647
648
649
650
651
652

653
654
655
656
657
658
659
660







-
+








-
+







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
The Text widget attempts to improve performance 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
On unix, the low level scrolling is done by XCopyArea, 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
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
677
678
679
680
681
682
683

684
685
686
687
688
689
690
691







-
+







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>>,
dark colors. Tk 8.6 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.

Changes to macosx/Tk-Common.xcconfig.
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46


19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44


45
46







-
+












-
+





-
-
+
+
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)
WARNING_CFLAGS = -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-value -Winit-self -Wpointer-arith -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_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.7
TK_DEFS = HAVE_TK_CONFIG_H
VERSION = 8.6
Changes to macosx/Tk-Release.xcconfig.
9
10
11
12
13
14
15
16

17
18
19
9
10
11
12
13
14
15

16
17
18
19







-
+



// 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_OPTIMIZATION_LEVEL = 2
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG $(TCL_DEFS) $(TK_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
CONFIGURE_ARGS = --disable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
MAKE_TARGET = deploy
Changes to macosx/Tk.xcode/project.pbxproj.
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
592
593
594
595
596
597
598

599
600
601
602
603
604
605







-







		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 */; };
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052







+







		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>"; };
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
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







-
+
















-







		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>"; };
		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>"; };
1206
1207
1208
1209
1210
1211
1212
1213

1214
1215

1216
1217
1218
1219
1220

1221
1222
1223
1224
1225
1226
1227
1205
1206
1207
1208
1209
1210
1211

1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228







-
+


+





+







		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>"; };
		F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; 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>"; };
1908
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
1923







-
+







		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>"; };
		F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; 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>"; };
1933
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
1948







-
+







		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>"; };
		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>"; };
1977
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1992







-
+







		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>"; };
		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; 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>"; };
2579
2580
2581
2582
2583
2584
2585

2586
2587
2588
2589
2590
2591
2592
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594







+







				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 */,
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
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







-
+

















-







			sourceTree = "<group>";
		};
		F966BC6B08F27A3D005CB29B /* unix */ = {
			isa = PBXGroup;
			children = (
				F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
				F966BC6D08F27A3D005CB29B /* configure */,
				F966BC6E08F27A3D005CB29B /* configure.ac */,
				F966BC6E08F27A3D005CB29B /* configure.in */,
				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 */,
2779
2780
2781
2782
2783
2784
2785
2786

2787
2788

2789
2790
2791
2792
2793
2794
2795
2780
2781
2782
2783
2784
2785
2786

2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797







-
+


+







		};
		F966BC9208F27A3D005CB29B /* win */ = {
			isa = PBXGroup;
			children = (
				F966BC9408F27A3D005CB29B /* aclocal.m4 */,
				F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
				F966BC9608F27A3E005CB29B /* configure */,
				F966BC9708F27A3E005CB29B /* configure.ac */,
				F966BC9708F27A3E005CB29B /* configure.in */,
				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 */,
3713
3714
3715
3716
3717
3718
3719
3720

3721
3722
3723
3724
3725
3726
3727
3715
3716
3717
3718
3719
3720
3721

3722
3723
3724
3725
3726
3727
3728
3729







-
+







			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D43D208F272B8004A47F5 /* configure */,
				F96D43D308F272B8004A47F5 /* configure.ac */,
				F96D43D308F272B8004A47F5 /* configure.in */,
				F96D442208F272B8004A47F5 /* eolFix.tcl */,
				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442A08F272B8004A47F5 /* Makefile.in */,
3746
3747
3748
3749
3750
3751
3752
3753

3754
3755
3756
3757
3758
3759
3760
3748
3749
3750
3751
3752
3753
3754

3755
3756
3757
3758
3759
3760
3761
3762







-
+







			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.ac */,
				F96D444208F272B9004A47F5 /* configure.in */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
3807
3808
3809
3810
3811
3812
3813
3814

3815
3816
3817
3818
3819
3820
3821
3809
3810
3811
3812
3813
3814
3815

3816
3817
3818
3819
3820
3821
3822
3823







-
+







		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.ac */,
				F96D447508F272BA004A47F5 /* configure.in */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
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
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







-
+












-
+









-
+










-
+









-
+












-
+









-
+










-
+







		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/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",
			);
			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";
			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    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/configure.in",
				"$(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";
			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    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/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",
			);
			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";
			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    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/configure.in",
				"$(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";
			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    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;
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4637
4638
4639
4640
4641
4642
4643

4644
4645
4646
4647
4648
4649
4650







-







				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 */,
Changes to macosx/Tk.xcodeproj/project.pbxproj.
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
592
593
594
595
596
597
598

599
600
601
602
603
604
605







-







		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 */; };
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052







+







		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>"; };
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
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







-
+
















-







		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>"; };
		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>"; };
1206
1207
1208
1209
1210
1211
1212
1213

1214
1215

1216
1217
1218
1219
1220

1221
1222
1223
1224
1225
1226
1227
1205
1206
1207
1208
1209
1210
1211

1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228







-
+


+





+







		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>"; };
		F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; 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>"; };
1908
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
1923







-
+







		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>"; };
		F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; 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>"; };
1933
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
1948







-
+







		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>"; };
		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>"; };
1977
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1992







-
+







		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>"; };
		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; 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>"; };
2579
2580
2581
2582
2583
2584
2585

2586
2587
2588
2589
2590
2591
2592
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594







+







				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 */,
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
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







-
+

















-







			sourceTree = "<group>";
		};
		F966BC6B08F27A3D005CB29B /* unix */ = {
			isa = PBXGroup;
			children = (
				F966BC6C08F27A3D005CB29B /* aclocal.m4 */,
				F966BC6D08F27A3D005CB29B /* configure */,
				F966BC6E08F27A3D005CB29B /* configure.ac */,
				F966BC6E08F27A3D005CB29B /* configure.in */,
				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 */,
2779
2780
2781
2782
2783
2784
2785
2786

2787
2788

2789
2790
2791

2792
2793
2794
2795
2796
2797
2798
2780
2781
2782
2783
2784
2785
2786

2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801







-
+


+



+







		};
		F966BC9208F27A3D005CB29B /* win */ = {
			isa = PBXGroup;
			children = (
				F966BC9408F27A3D005CB29B /* aclocal.m4 */,
				F966BC9508F27A3D005CB29B /* buildall.vc.bat */,
				F966BC9608F27A3E005CB29B /* configure */,
				F966BC9708F27A3E005CB29B /* configure.ac */,
				F966BC9708F27A3E005CB29B /* configure.in */,
				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 */,
3712
3713
3714
3715
3716
3717
3718
3719

3720
3721
3722
3723
3724
3725
3726
3715
3716
3717
3718
3719
3720
3721

3722
3723
3724
3725
3726
3727
3728
3729







-
+







			sourceTree = "<group>";
		};
		F96D43D008F272B8004A47F5 /* tools */ = {
			isa = PBXGroup;
			children = (
				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
				F96D43D208F272B8004A47F5 /* configure */,
				F96D43D308F272B8004A47F5 /* configure.ac */,
				F96D43D308F272B8004A47F5 /* configure.in */,
				F96D442208F272B8004A47F5 /* eolFix.tcl */,
				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
				F96D442508F272B8004A47F5 /* genStubs.tcl */,
				F96D442708F272B8004A47F5 /* index.tcl */,
				F96D442808F272B8004A47F5 /* installData.tcl */,
				F96D442908F272B8004A47F5 /* loadICU.tcl */,
				F96D442A08F272B8004A47F5 /* Makefile.in */,
3745
3746
3747
3748
3749
3750
3751
3752

3753
3754
3755
3756
3757
3758
3759
3748
3749
3750
3751
3752
3753
3754

3755
3756
3757
3758
3759
3760
3761
3762







-
+







			sourceTree = "<group>";
		};
		F96D443E08F272B9004A47F5 /* unix */ = {
			isa = PBXGroup;
			children = (
				F96D444008F272B9004A47F5 /* aclocal.m4 */,
				F96D444108F272B9004A47F5 /* configure */,
				F96D444208F272B9004A47F5 /* configure.ac */,
				F96D444208F272B9004A47F5 /* configure.in */,
				F96D444308F272B9004A47F5 /* dltest */,
				F96D444D08F272B9004A47F5 /* install-sh */,
				F96D444E08F272B9004A47F5 /* installManPage */,
				F96D444F08F272B9004A47F5 /* ldAix */,
				F96D445008F272B9004A47F5 /* Makefile.in */,
				F96D445208F272B9004A47F5 /* README */,
				F96D445308F272B9004A47F5 /* tcl.m4 */,
3806
3807
3808
3809
3810
3811
3812
3813

3814
3815
3816
3817
3818
3819
3820
3809
3810
3811
3812
3813
3814
3815

3816
3817
3818
3819
3820
3821
3822
3823







-
+







		F96D446E08F272B9004A47F5 /* win */ = {
			isa = PBXGroup;
			children = (
				F96D447008F272BA004A47F5 /* aclocal.m4 */,
				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
				F96D447208F272BA004A47F5 /* cat.c */,
				F96D447408F272BA004A47F5 /* configure */,
				F96D447508F272BA004A47F5 /* configure.ac */,
				F96D447508F272BA004A47F5 /* configure.in */,
				F96D447708F272BA004A47F5 /* Makefile.in */,
				F96D447808F272BA004A47F5 /* makefile.vc */,
				F96D447908F272BA004A47F5 /* nmakehlp.c */,
				F96D447A08F272BA004A47F5 /* README */,
				F96D447C08F272BA004A47F5 /* rules.vc */,
				F96D447D08F272BA004A47F5 /* stub16.c */,
				F96D447E08F272BA004A47F5 /* tcl.dsp */,
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
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







-
+












-
+









-
+










-
+









-
+












-
+









-
+










-
+







		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
				"$(TCL_SRCROOT)/macosx/configure.ac",
				"$(TCL_SRCROOT)/unix/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",
			);
			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";
			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    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/configure.in",
				"$(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";
			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    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/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",
			);
			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";
			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    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/configure.in",
				"$(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";
			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    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;
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4640
4641
4642
4643
4644
4645
4646

4647
4648
4649
4650
4651
4652
4653







-







				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 */,
Changes to macosx/configure.ac.
1
2
3
4
5
6
7
8
9
10
11

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)
m4_include(../unix/configure.in)
Changes to macosx/tkMacOSX.h.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * tkMacOSX.h --
 *
 *	Declarations of Macintosh specific exported variables and procedures.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 _TKMAC
#define _TKMAC
Changes to macosx/tkMacOSXBitmap.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
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34





-
-
-
+
+
+







+










-
+







/*
 * tkMacOSXBitmap.c --
 *
 *	This file handles the implementation of native bitmaps.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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. */
} BuiltInIcon;

/*
 * This array mapps a string name to the supported builtin icons
 * This array maps a string name to the supported builtin icons
 * on the Macintosh.
 */

static BuiltInIcon builtInIcons[] = {
    {"document",	kGenericDocumentIcon},
    {"stationery",	kGenericStationeryIcon},
    {"edition",		kGenericEditionFileIcon},
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
46
47
48
49
50
51
52



53
54
55
56
57
58
59







-
-
-







    {"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[] = {
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143







-
+







    Display *display,
    NSImage* image,
    CGSize size)
{
    TkMacOSXDrawingContext dc;
    Pixmap pixmap;

    pixmap = Tk_GetPixmap(display, None, size.width, size.height, 0);
    pixmap = Tk_GetPixmap(display, None, (int)size.width, (int)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)];
170
171
172
173
174
175
176
177
178


179
180
181

182
183
184
185
186
187
188
168
169
170
171
172
173
174


175
176

177

178
179
180
181
182
183
184
185







-
-
+
+
-

-
+







 */

Pixmap
TkpCreateNativeBitmap(
    Display *display,
    const void *source)		/* Info about the icon to build. */
{
    NSString *iconUTI = OSTYPE_TO_UTI(PTR2UINT(source));
    NSImage *iconImage = [[NSWorkspace sharedWorkspace]
    NSString *filetype = TkMacOSXOSTypeToUTI(PTR2UINT(source));
    NSImage *iconImage = TkMacOSXIconForFileType(filetype);
			     iconForFileType: iconUTI];
    CGSize size = CGSizeMake(builtInIconSize, builtInIconSize);
    Pixmap pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
    Pixmap pixmap = PixmapFromImage(display, iconImage, size);
    return pixmap;
}


/*
 *----------------------------------------------------------------------
 *
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
269
270
271

272
273
274
275
276


277
278
279
280
281
282
283
246
247
248
249
250
251
252

253
254
255

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 *height)
{
    Tcl_HashEntry *hPtr;
    Pixmap pixmap = None;
    NSString *string;
    NSImage *image = nil;
    NSSize size = { .width = builtInIconSize, .height = builtInIconSize };

    if (iconBitmapTable.buckets &&
	    (hPtr = Tcl_FindHashEntry(&iconBitmapTable, name))) {
	OSType type;
	IconBitmap *iconBitmap = Tcl_GetHashValue(hPtr);
	IconBitmap *iconBitmap = (IconBitmap *)Tcl_GetHashValue(hPtr);
	name = NULL;
	size = NSMakeSize(iconBitmap->width, iconBitmap->height);
	switch (iconBitmap->kind) {
	case ICON_FILE:
	    string = [[NSString stringWithUTF8String:iconBitmap->value]
		    stringByExpandingTildeInPath];
	    image = [[NSWorkspace sharedWorkspace] iconForFile:string];
	    break;
	case ICON_FILETYPE:
	    string = [NSString stringWithUTF8String:iconBitmap->value];
	    image = [[NSWorkspace sharedWorkspace] iconForFileType:string];
	    image = TkMacOSXIconForFileType(string);
	    break;
	case ICON_OSTYPE:
	    if (OSTypeFromString(iconBitmap->value, &type) == TCL_OK) {
		string = NSFileTypeForHFSTypeCode(type);
		image = [[NSWorkspace sharedWorkspace] iconForFileType:string];
		string = [NSString stringWithUTF8String:iconBitmap->value];
		image = TkMacOSXIconForFileType(string);
	    }
	    break;
	case ICON_SYSTEMTYPE:
	    name = iconBitmap->value;
	    break;
	case ICON_NAMEDIMAGE:
	    string = [NSString stringWithUTF8String:iconBitmap->value];
304
305
306
307
308
309
310
311
312
313
314





315
316
317
318


319
320
321
322


323
324
325
326
327
328
329
300
301
302
303
304
305
306


307
308
309
310
311
312
313
314
315


316
317

318
319
320
321
322
323
324
325
326
327
328
329







-
-


+
+
+
+
+


-
-
+
+
-



+
+







	    }
	}
	if (image) {
	    size = [image size];
	}
    }
    if (image) {
	*width = size.width;
	*height = size.height;
	pixmap = PixmapFromImage(display, image, NSSizeToCGSize(size));
    } else if (name) {
	/*
	 * As a last resort, try to interpret the name as an OSType.
	 * It would probably be better to just return None at this
	 * point.
	 */
	OSType iconType;
	if (OSTypeFromString(name, &iconType) == TCL_OK) {
	    NSString *iconUTI = OSTYPE_TO_UTI(iconType);
	    NSImage *iconImage = [[NSWorkspace sharedWorkspace]
	    NSString *iconUTI = TkMacOSXOSTypeToUTI(iconType);
	    NSImage *iconImage = TkMacOSXIconForFileType(iconUTI);
				     iconForFileType: iconUTI];
	    pixmap = PixmapFromImage(display, iconImage, NSSizeToCGSize(size));
	}
    }
    *width = (int)size.width;
    *height = (int)size.height;
    return pixmap;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIconBitmapObjCmd --
343
344
345
346
347
348
349
350


351
352
353
354
355
356
357
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358







-
+
+







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;
    int isNew, result = TCL_ERROR;
    int i = 1, len;
    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");
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







-
+







    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);
	iconBitmap = (IconBitmap *)Tcl_GetHashValue(hPtr);
	ckfree(iconBitmap->value);
    } else {
	iconBitmap = (IconBitmap *)ckalloc(sizeof(IconBitmap));
	Tcl_SetHashValue(hPtr, iconBitmap);
    }
    *iconBitmap = ib;
    result = TCL_OK;
Changes to macosx/tkMacOSXButton.c.
1
2
3
4
5
6
7
8
9
10
11
12






13
14
15
16
17
18
19
1
2
3
4
5
6






7
8
9
10
11
12
13
14
15
16
17
18
19






-
-
-
-
-
-
+
+
+
+
+
+







/*
 * 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.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001 Apple Computer, Inc.
 * Copyright © 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"
177
178
179
180
181
182
183
184
185


186
187
188
189
190
191
192
177
178
179
180
181
182
183


184
185
186
187
188
189
190
191
192







-
-
+
+







 *----------------------------------------------------------------------
 */

void
TkpDisplayButton(
    ClientData clientData)	/* Information about widget. */
{
    MacButton *macButtonPtr = clientData;
    TkButton *butPtr = clientData;
    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)) {
405
406
407
408
409
410
411
412

413
414
415

416
417
418
419
420
421
422
405
406
407
408
409
410
411

412
413
414

415
416
417
418
419
420
421
422







-
+


-
+







	 * 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;
	    height = (int)contBounds.size.height;
        }
        if (width < contBounds.size.width) {
	    width = contBounds.size.width;
	    width = (int)contBounds.size.width;
        }
	height += 2*HI_PADY;
	width += 2*HI_PADX;
    }
    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}
761
762
763
764
765
766
767

768
769
770
771





772
773
774
775
776
777
778
761
762
763
764
765
766
767
768




769
770
771
772
773
774
775
776
777
778
779
780







+
-
-
-
-
+
+
+
+
+







	/*
	 * 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 ([NSApp macOSVersion] < 101500) {
	if (TkMacOSXInDarkMode(butPtr->tkwin) &&
	    mbPtr->drawinfo.state != kThemeStatePressed &&
	    !(mbPtr->drawinfo.adornment & kThemeAdornmentDefault)) {
	    hiinfo.state = kThemeStateInactive;
	    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);
897
898
899
900
901
902
903
904
905


906
907
908
909
910
911
912
899
900
901
902
903
904
905


906
907
908
909
910
911
912
913
914







-
-
+
+







 */

static void
ButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkButton *buttonPtr = clientData;
    MacButton *mbPtr = clientData;
    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) {
953
954
955
956
957
958
959
960

961
962
963
964
965
966
967
955
956
957
958
959
960
961

962
963
964
965
966
967
968
969







-
+







        *btnkind = kThemeBevelButton;
    } else if (butPtr->borderWidth == 4) {
        *btnkind = kThemeRoundedBevelButton;
    } else {
        *btnkind = kThemePushButton;
    }

    if ((butPtr->image == None) && (butPtr->bitmap == None)) {
    if ((butPtr->image == NULL) && (butPtr->bitmap == None)) {
        switch (butPtr->type) {
	case TYPE_BUTTON:
	    *btnkind = kThemePushButton;
	    break;
	case TYPE_RADIO_BUTTON:
	    if (butPtr->borderWidth <= 1) {
		*btnkind = kThemeSmallRadioButton;
1170
1171
1172
1173
1174
1175
1176
1177

1178
1179
1180
1181
1182
1183
1184
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1186







-
+







 *
 *--------------------------------------------------------------
 */

static void
PulseDefaultButtonProc(ClientData clientData)
{
    MacButton *mbPtr = clientData;
    MacButton *mbPtr = (MacButton *)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).
Changes to macosx/tkMacOSXClipboard.c.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * tkMacOSXClipboard.c --
 *
 *	This file manages the clipboard for the Tk toolkit.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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"
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47







-
+







		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];
						   length:(NSUInteger)cbPtr->length];
		    [string appendString:s];
		    [s release];
		}
		break;
	    }
	}
    }
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153
133
134
135
136
137
138
139


140





141
142
143
144
145
146
147







-
-
+
-
-
-
-
-







	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);
	    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);
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
170
171
172
173
174
175
176

177
178
179
180
181
182
183







-







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];
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
1
2
3
4
5
6
7





8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55







-
-
-
-
-
+
+
+
+
+













+

+






+




-
+






-
+
+







/*
 * 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
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 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 controlAlternatingRowIndex;
static int selectedTabTextIndex;
static int pressedButtonTextIndex;
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()
static 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;
    int newPtr;
    int 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];
63
64
65
66
67
68
69
70



71
72
73
74
75
76
77
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83







-
+
+
+







	    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"]) {
		} else if (   ![colorName isEqualToString:@"selectedTabTextColor"]
			   && ![colorName isEqualToString:@"controlAlternatingRowColor"]
			   && ![colorName isEqualToString:@"pressedButtonTextColor"]) {
		    /* Uncomment to print all unsupported colors:              */
		    /* printf("Unsupported color %s\n", colorName.UTF8String); */
		    continue;
		}
	    }
	    entry->selector = [colorName retain];
	}
86
87
88
89
90
91
92
93

94
95
96
97
98
99

100
101
102
103
104
105
106
92
93
94
95
96
97
98

99
100
101
102
103
104

105
106
107
108
109
110
111
112







-
+





-
+







    }

    /*
     * Add all of the colors in the System ColorList.
     */

    for (key in [systemColorList allKeys]) {
	int length = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
	NSUInteger 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]);
	name[0] = (char)toupper(UCHAR(name[0]));
        if (!strcmp(name, "WindowBackgroundColor")) {

	    /*
	     * Avoid black windows on old systems.
	     */

	    continue;
140
141
142
143
144
145
146



147
148
149



150
151
152
153
154
155
156
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168







+
+
+



+
+
+








    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, "ControlAlternatingRowColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    controlAlternatingRowIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "SelectedTabTextColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    selectedTabTextIndex = entry->index;
    hPtr = Tcl_FindHashEntry(&systemColors, "PressedButtonTextColor");
    entry = (SystemColorDatum *) Tcl_GetHashValue(hPtr);
    pressedButtonTextIndex = entry->index;
    [pool drain];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRGBPixel --
173
174
175
176
177
178
179
180

181
182

183
184

185
186
187
188
189
190
191
185
186
187
188
189
190
191

192
193

194
195

196
197
198
199
200
201
202
203







-
+

-
+

-
+







MODULE_SCOPE
unsigned long
TkMacOSXRGBPixel(
    unsigned long red,
    unsigned long green,
    unsigned long blue)
{
    MacPixel p;
    MacPixel p = {0};
    p.pixel.colortype = rgbColor;
    p.pixel.value = ((red & 0xff) << 16)  |
    p.pixel.value = (unsigned int)(((red & 0xff) << 16)  |
	            ((green & 0xff) << 8) |
	            (blue & 0xff);
	            (blue & 0xff));
    return p.ulong;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXClearPixel --
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229







-
+







 *	None.
 *----------------------------------------------------------------------
 */
MODULE_SCOPE
unsigned long TkMacOSXClearPixel(
    void)
{
    MacPixel p;
    MacPixel p = {0};
    p.pixel.value = 0;
    p.pixel.colortype = clearColor;
    return p.ulong;
}


/*
228
229
230
231
232
233
234
235

236
237
238
239

240
241
242
243
244
245
246
240
241
242
243
244
245
246

247
248
249
250

251
252
253
254
255
256
257
258







-
+



-
+







 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

SystemColorDatum*
static SystemColorDatum*
GetEntryFromPixel(
    unsigned long pixel)
{
    MacPixel p;
    MacPixel p = {0};
    int index = rgbColorIndex;

    p.ulong = pixel;
    if (p.pixel.colortype != rgbColor) {
	index = p.pixel.value;
    }
    if (index < numSystemColors) {
274
275
276
277
278
279
280

281
282
283
284

285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314




315
316
317
318
319
320
321









322
323
324
325








326
327
328
329
330
331
332
333






















334
335
336
337
338
339
340
341
342
343
344
345
346
347
348






349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365





366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365


366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438




439
440
441
442
443
444
445







+




+










-
+



















+
+
+
+







+
+
+
+
+
+
+
+
+

-


+
+
+
+
+
+
+
+






-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+















+
+
+
+
+
+

















+
+
+
+
+








-
-
-
-







static void
GetRGBA(
    SystemColorDatum *entry,
    unsigned long pixel,
    CGFloat *rgba)
{
    NSColor *bgColor, *color = nil;
    int OSVersion = [NSApp macOSVersion];

    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.
	 * 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 clearColor:
	rgba[0] = rgba[1] = rgba[2] = 1.0;
	rgba[3] = 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 == controlAlternatingRowIndex) {
	    /*
	     * Color which is now called alternatingContentBackgroundColor on 10.14.
	     * Taken from NSColor.controlAlternatingRowBackgroundColors (which was
	     * replaced by NSColor.alternatingContentBackgroundColors on 10.14).
	     */
	    color = [[NSColor colorWithCatalogName:@"System"
					 colorName:@"controlAlternatingRowColor"]
			colorUsingColorSpace:sRGB];
	} else if (entry->index == selectedTabTextIndex) {
	    int OSVersion = [NSApp macOSVersion];
	    if (OSVersion > 100600 && OSVersion < 110000) {
		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
	    } else {
		color = [[NSColor textColor] colorUsingColorSpace:sRGB];
	    }
	} else if (entry->index == pressedButtonTextIndex) {
	    if (OSVersion < 120000) {
		color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
	    } else {
		color = [[NSColor blackColor] colorUsingColorSpace:sRGB];
	    }
	} else {
	    color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
	}
	[color getComponents: rgba];
	break;
    case clearColor:
	rgba[3] = 0;
    case HIText:
#ifdef __LP64__
	color = [[NSColor textColor] colorUsingColorSpace:sRGB];
	[color getComponents: rgba];
#else
	{
	    OSStatus err = noErr;
	    RGBColor rgb;
	    err = GetThemeTextColor(kThemeTextColorPushButtonActive, 32,
                    true, &rgb);
	    if (err == noErr) {
		rgba[0] = (CGFloat) rgb.red / 65535;
		rgba[1] = (CGFloat) rgb.green / 65535;
		rgba[2] = (CGFloat) rgb.blue / 65535;
	    }
	}
#endif
	break;
    case HIBackground:
	color = [[NSColor windowBackgroundColor] colorUsingColorSpace:sRGB];
	[color getComponents: rgba];
	break;
    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.
 *
 *      In 64 bit macOS systems there are no HITheme functions which convert
 *      HIText or HIBackground colors to CGColors.  (GetThemeTextColor was
 *      removed, and it was never possible with backgrounds.)  On 64-bit systems
 *      we replace all HIText colors by systemTextColor and all HIBackground
 *      colors by systemWindowBackgroundColor.
 *
 * 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};

    if (entry->type == HIBrush) {
     	OSStatus err = ChkErr(HIThemeBrushCreateCGColor, entry->value, c);
     	return err == noErr;
    }

    /*
     * 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;
}

/*
408
409
410
411
412
413
414
415

416
417
418


419
420
421
422
423
424
425
426
427
428
429
430
431

432
433
434
435
436
437

438
439
440
441
442
443
444
445
446


447
448
449
450
451
452
453
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
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







-
+



+
+












-
+





-
+
-






-
-
+
+










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




















-
+


-
+


+

-
-
-
-
-
-
+
+
+
-
-
+







	NSView *view = nil;
	if (winPtr && winPtr->privatePtr) {
	    view = TkMacOSXGetNSViewForDrawable((Drawable)winPtr->privatePtr);
	}
	if (view) {
	    name = [[view effectiveAppearance] name];
	} else {
	    name = [[NSAppearance currentAppearance] name];
	    name = [[NSApp effectiveAppearance] name];
	}
	return (name == NSAppearanceNameDarkAqua);
    }
#else
    (void) tkwin;
#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.
 *      value.  The parameter macColor should be a pointer to a CGColorRef.
 *
 * 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
 *	The CGColorRef referenced by the variable macColor may be modified.
 *	responsible for releasing it!
 *
 *----------------------------------------------------------------------
 */

int
TkSetMacColor(
    unsigned long pixel,		/* Pixel value to convert. */
    void *macColor)			/* CGColorRef to modify. */
    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 --
 *
 *	Maintain a per-GC cache of previously converted CGColorRefs
 *
 * Results:
 *	None resp. retained CGColorRef for CopyCachedColor()
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpInitGCCache(
    GC gc)
{
    bzero(TkpGetGCCache(gc), sizeof(TkpGCCache));
}

void
TkpFreeGCCache(
    GC gc)
{
    TkpGCCache *gcCache = TkpGetGCCache(gc);

    if (gcCache->cachedForegroundColor) {
	CFRelease(gcCache->cachedForegroundColor);
    }
    if (gcCache->cachedBackgroundColor) {
	CFRelease(gcCache->cachedBackgroundColor);
    }
}

static CGColorRef
CopyCachedColor(
    GC gc,
    unsigned long pixel)
{
    TkpGCCache *gcCache = TkpGetGCCache(gc);
    CGColorRef cgColor = NULL;

    if (gcCache) {
	if (gcCache->cachedForeground == pixel) {
	    cgColor = gcCache->cachedForegroundColor;
	} else if (gcCache->cachedBackground == pixel) {
	    cgColor = gcCache->cachedBackgroundColor;
	}
	if (cgColor) {
	    CFRetain(cgColor);
	}
    }
    return cgColor;
}

static void
SetCachedColor(
    GC gc,
    unsigned long pixel,
    CGColorRef cgColor)
{
    TkpGCCache *gcCache = TkpGetGCCache(gc);

    if (gcCache && cgColor) {
	if (gc->foreground == pixel) {
	    if (gcCache->cachedForegroundColor) {
		CFRelease(gcCache->cachedForegroundColor);
	    }
	    gcCache->cachedForegroundColor = (CGColorRef) CFRetain(cgColor);
	    gcCache->cachedForeground = pixel;
	} else if (gc->background == pixel) {
	    if (gcCache->cachedBackgroundColor) {
		CFRelease(gcCache->cachedBackgroundColor);
	    }
	    gcCache->cachedBackgroundColor = (CGColorRef) CFRetain(cgColor);
	    gcCache->cachedBackground = pixel;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGColor --
 *
 *	Creates a CGColorRef from a X style pixel value.
 *
 * Results:
 *	Returns NULL if not a real pixel, CGColorRef otherwise.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

CGColorRef
TkMacOSXCreateCGColor(
    GC gc,
    unsigned long pixel)		/* Pixel value to convert. */
{
    CGColorRef cgColor = CopyCachedColor(gc, pixel);

    if (!cgColor && TkSetMacColor(pixel, &cgColor)) {
	SetCachedColor(gc, pixel, cgColor);
    }
    return cgColor;
}

/*
 *----------------------------------------------------------------------
 *
 * 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,
    TCL_UNUSED(GC),
    unsigned long pixel)		/* Pixel value to convert. */
{
    CGColorRef cgColor = TkMacOSXCreateCGColor(gc, pixel);
    CGColorRef cgColor = NULL;
    NSColor *nsColor = nil;

    TkSetMacColor(pixel, &cgColor);
    if (cgColor) {
	NSColorSpace *colorSpace = [[NSColorSpace alloc]
		initWithCGColorSpace:CGColorGetColorSpace(cgColor)];

	nsColor = [NSColor colorWithColorSpace:colorSpace
		components:CGColorGetComponents(cgColor)
		count:CGColorGetNumberOfComponents(cgColor)];
	nsColor = [NSColor colorWithColorSpace:sRGB
			components:CGColorGetComponents(cgColor)
			count:(NSInteger)CGColorGetNumberOfComponents(cgColor)];
	[colorSpace release];
	CFRelease(cgColor);
	CGColorRelease(cgColor);
    }
    return nsColor;
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+




-
+

+
+











+
+
+
+
+
+
+
+
+
+

-
+
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetColorInContext(
    GC gc,
    TCL_UNUSED(GC),
    unsigned long pixel,
    CGContextRef context)
{
    OSStatus err = noErr;
    CGColorRef cgColor = nil;
    CGColorRef cgColor = NULL;
    SystemColorDatum *entry = GetEntryFromPixel(pixel);
    CGRect rect;
    HIThemeBackgroundDrawInfo info = {0, kThemeStateActive, 0};

    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;
	case HIText:
	    err = ChkErr(HIThemeSetTextFill, entry->value, NULL, context,
		    kHIThemeOrientationNormal);
	    break;
	case HIBackground:
	    info.kind = entry->value;
	    rect = CGContextGetClipBoundingBox(context);
	    err = ChkErr(HIThemeApplyBackground, &rect, &info,
		    context, kHIThemeOrientationNormal);
	    break;
	default:
	    if (SetCGColorComponents(entry, pixel, &cgColor)){
	    SetCGColorComponents(entry, pixel, &cgColor);
		SetCachedColor(gc, pixel, cgColor);
	    }
	    break;
	}
    }
    if (cgColor) {
	CGContextSetFillColorWithColor(context, cgColor);
	CGContextSetStrokeColorWithColor(context, cgColor);
	CGColorRelease(cgColor);
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
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







-



-














-
+



-
+


-
+





-
-
+


+
+






+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+






-
-
-
+
+
+







-
-
-
+
+
+


-
+







{
    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;
	MacPixel p = {0};

	if (hPtr != NULL) {
	    SystemColorDatum *entry = (SystemColorDatum *)Tcl_GetHashValue(hPtr);
	    CGColorRef c;
	    CGColorRef c = NULL;

	    p.pixel.colortype = entry->type;
	    p.pixel.value = entry->index;
	    p.pixel.value = (unsigned int)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;
		    NSAppearance *windowAppearance;
		    if (view) {
			windowAppearance = [view effectiveAppearance];
		    } else {
			windowAppearance = [NSApp effectiveAppearance];
		    }
		    if ([windowAppearance name] == NSAppearanceNameDarkAqua) {
			colormap = darkColormap;
		    } else {
			colormap = lightColormap;
		    }
		    if (@available(macOS 11.0, *)) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
			CGFloat *rgbaPtr = rgba;
			[windowAppearance performAsCurrentDrawingAppearance:^{
				GetRGBA(entry, p.ulong, rgbaPtr);
			    }];
#endif
		    } else {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
			NSAppearance *savedAppearance = [NSAppearance currentAppearance];
		    [NSAppearance setCurrentAppearance:windowAppearance];
		    GetRGBA(entry, p.ulong, rgba);
		    [NSAppearance setCurrentAppearance:savedAppearance];
			[NSAppearance setCurrentAppearance:windowAppearance];
			GetRGBA(entry, p.ulong, rgba);
			[NSAppearance setCurrentAppearance:savedAppearance];
#endif
		    }
		} 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;
		color.red   = (unsigned short)(rgba[0] * 65535.0);
		color.green = (unsigned short)(rgba[1] * 65535.0);
		color.blue  = (unsigned short)(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;
		    color.red   = (unsigned short)(rgba[0] * 65535.0);
		    color.green = (unsigned short)(rgba[1] * 65535.0);
		    color.blue  = (unsigned short)(rgba[2] * 65535.0);
		    break;
		case 2:
		    color.red = color.green = color.blue = rgba[0] * 65535.0;
		    color.red = color.green = color.blue = (unsigned short)(rgba[0] * 65535.0);
		    break;
		default:
		    Tcl_Panic("CGColor with %d components", (int) n);
		}
		CGColorRelease(c);
		goto validXColor;
	    }
838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820







-
+








Status
XAllocColor(
    Display *display,		/* Display. */
    TCL_UNUSED(Colormap),		/* Not used. */
    XColor *colorPtr)		/* XColor struct to modify. */
{
    display->request++;
    LastKnownRequestProcessed(display)++;
    colorPtr->pixel = TkpGetPixel(colorPtr);
    return 1;
}

Colormap
XCreateColormap(
    TCL_UNUSED(Display *),		/* Display. */
Changes to macosx/tkMacOSXColor.h.
34
35
36
37
38
39
40


41
42
43
44
45
46
47
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49







+
+







 * 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.*/
    HIText,        /* A HITheme text color (32-bit only). */
    HIBackground,  /* A HITheme background color (32-bit only). */
    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;
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99







-
+







 * 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 },
{"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 },
157
158
159
160
161
162
163
































































164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179


180
181
182
183
184
185
186



187

188
189
190
191
192
193
194
195
196
197
198
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267
268
269







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+














-
+

+
+







+
+
+
-
+











{"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 },

{"ButtonText",				HIText,   kThemeTextColorPushButtonActive, NULL, 0, NULL },
{"MenuActiveText",			HIText,   kThemeTextColorMenuItemSelected, NULL, 0, NULL },
{"MenuDisabled",			HIText,   kThemeTextColorMenuItemDisabled, NULL, 0, NULL },
{"MenuText",				HIText,   kThemeTextColorMenuItemActive, NULL, 0, NULL },
{"BlackText",				HIText,   kThemeTextColorBlack, NULL, 0, NULL },
{"DialogActiveText",			HIText,   kThemeTextColorDialogActive, NULL, 0, NULL },
{"DialogInactiveText",			HIText,   kThemeTextColorDialogInactive, NULL, 0, NULL },
{"AlertActiveText",			HIText,   kThemeTextColorAlertActive, NULL, 0, NULL },
{"AlertInactiveText",			HIText,   kThemeTextColorAlertInactive, NULL, 0, NULL },
{"ModelessDialogActiveText",		HIText,   kThemeTextColorModelessDialogActive, NULL, 0, NULL },
{"ModelessDialogInactiveText",		HIText,   kThemeTextColorModelessDialogInactive, NULL, 0, NULL },
{"WindowHeaderActiveText",		HIText,   kThemeTextColorWindowHeaderActive, NULL, 0, NULL },
{"WindowHeaderInactiveText",		HIText,   kThemeTextColorWindowHeaderInactive, NULL, 0, NULL },
{"PlacardActiveText",			HIText,   kThemeTextColorPlacardActive, NULL, 0, NULL },
{"PlacardInactiveText",			HIText,   kThemeTextColorPlacardInactive, NULL, 0, NULL },
{"PlacardPressedText",			HIText,   kThemeTextColorPlacardPressed, NULL, 0, NULL },
{"PushButtonActiveText",		HIText,   kThemeTextColorPushButtonActive, NULL, 0, NULL },
{"PushButtonInactiveText",		HIText,   kThemeTextColorPushButtonInactive, NULL, 0, NULL },
{"PushButtonPressedText",		HIText,   kThemeTextColorPushButtonPressed, NULL, 0, NULL },
{"BevelButtonActiveText",		HIText,   kThemeTextColorBevelButtonActive, NULL, 0, NULL },
{"BevelButtonInactiveText",		HIText,   kThemeTextColorBevelButtonInactive, NULL, 0, NULL },
{"BevelButtonPressedText",		HIText,   kThemeTextColorBevelButtonPressed, NULL, 0, NULL },
{"PopupButtonActiveText",		HIText,   kThemeTextColorPopupButtonActive, NULL, 0, NULL },
{"PopupButtonInactiveText",		HIText,   kThemeTextColorPopupButtonInactive, NULL, 0, NULL },
{"PopupButtonPressedText",		HIText,   kThemeTextColorPopupButtonPressed, NULL, 0, NULL },
{"IconLabelText",			HIText,   kThemeTextColorIconLabel, NULL, 0, NULL },
{"ListViewText",			HIText,   kThemeTextColorListView, NULL, 0, NULL },
{"DocumentWindowTitleActiveText",	HIText,   kThemeTextColorDocumentWindowTitleActive, NULL, 0, NULL },
{"DocumentWindowTitleInactiveText",	HIText,   kThemeTextColorDocumentWindowTitleInactive, NULL, 0, NULL },
{"MovableModalWindowTitleActiveText",  	HIText,   kThemeTextColorMovableModalWindowTitleActive, NULL, 0, NULL },
{"MovableModalWindowTitleInactiveText",	HIText,   kThemeTextColorMovableModalWindowTitleInactive, NULL, 0, NULL },
{"UtilityWindowTitleActiveText",	HIText,   kThemeTextColorUtilityWindowTitleActive, NULL, 0, NULL },
{"UtilityWindowTitleInactiveText",	HIText,   kThemeTextColorUtilityWindowTitleInactive, NULL, 0, NULL },
{"PopupWindowTitleActiveText",		HIText,   kThemeTextColorPopupWindowTitleActive, NULL, 0, NULL },
{"PopupWindowTitleInactiveText",	HIText,   kThemeTextColorPopupWindowTitleInactive, NULL, 0, NULL },
{"RootMenuActiveText",			HIText,   kThemeTextColorRootMenuActive, NULL, 0, NULL },
{"RootMenuSelectedText",		HIText,   kThemeTextColorRootMenuSelected, NULL, 0, NULL },
{"RootMenuDisabledText",		HIText,   kThemeTextColorRootMenuDisabled, NULL, 0, NULL },
{"MenuItemActiveText",			HIText,   kThemeTextColorMenuItemActive, NULL, 0, NULL },
{"MenuItemSelectedText",		HIText,   kThemeTextColorMenuItemSelected, NULL, 0, NULL },
{"MenuItemDisabledText",		HIText,   kThemeTextColorMenuItemDisabled, NULL, 0, NULL },
{"PopupLabelActiveText",		HIText,   kThemeTextColorPopupLabelActive, NULL, 0, NULL },
{"PopupLabelInactiveText",		HIText,   kThemeTextColorPopupLabelInactive, NULL, 0, NULL },
{"TabFrontActiveText",			HIText,   kThemeTextColorTabFrontActive, NULL, 0, NULL },
{"TabNonFrontActiveText",		HIText,   kThemeTextColorTabNonFrontActive, NULL, 0, NULL },
{"TabNonFrontPressedText",		HIText,   kThemeTextColorTabNonFrontPressed, NULL, 0, NULL },
{"TabFrontInactiveText",		HIText,   kThemeTextColorTabFrontInactive, NULL, 0, NULL },
{"TabNonFrontInactiveText",		HIText,   kThemeTextColorTabNonFrontInactive, NULL, 0, NULL },
{"IconLabelSelectedText",		HIText,   kThemeTextColorIconLabelSelected, NULL, 0, NULL },
{"BevelButtonStickyActiveText",		HIText,   kThemeTextColorBevelButtonStickyActive, NULL, 0, NULL },
{"BevelButtonStickyInactiveText",	HIText,   kThemeTextColorBevelButtonStickyInactive, NULL, 0, NULL },
{"NotificationText",			HIText,   kThemeTextColorNotification, NULL, 0, NULL },
{"SystemDetailText",			HIText,   kThemeTextColorSystemDetail, NULL, 0, NULL },
{"PlacardBackground",			HIBackground, kThemeBackgroundPlacard, NULL, 0, NULL },
{"WindowHeaderBackground",		HIBackground, kThemeBackgroundWindowHeader, NULL, 0, NULL },
{"ListViewWindowHeaderBackground",	HIBackground, kThemeBackgroundListViewWindowHeader, NULL, 0, NULL },
{"MetalBackground",			HIBackground, kThemeBackgroundMetal, NULL, 0, NULL },

{"SecondaryGroupBoxBackground",		HIBackground, kThemeBackgroundSecondaryGroupBox, NULL, 0, NULL },
{"TabPaneBackground",			HIBackground, kThemeBackgroundTabPane, NULL, 0, NULL },
{"WhiteText",				HIText,   kThemeTextColorWhite, NULL, 0, NULL },
{"Black",				HIBrush,  kThemeBrushBlack, NULL, 0, NULL },
{"White",				HIBrush,  kThemeBrushWhite, 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. */
/* Color to use for notebook tab label text -- depends on OS version. */
{"SelectedTabTextColor",	    semantic, 0, "textColor", 0, NULL },
/* Color to use for selected button labels -- depends on OS version. */
{"PressedButtonTextColor",	    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 },
{"UnemphasizedSelectedTextBackgroundColor", semantic, 0, "grayColor", 0, NULL },
/* This color is available since 10.3, so the fallback is unused */
{"ControlAlternatingRowColor",	    semantic, 0, "grayColor" , 0, NULL },
{NULL,				    0, 0, NULL, 0, NULL }
{NULL,				    rgbColor, 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.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33






-
-
+
+

















-
+







/*
 * tkMacOSXConfig.c --
 *
 *	This module implements the Macintosh system defaults for
 *	the configuration package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright 2001, Apple Inc.
 * Copyright © 1997 Sun Microsystems, Inc.
 * Copyright © 2001 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"


/*
 *----------------------------------------------------------------------
 *
 * TkpGetSystemDefault --
 *
 *	Given a dbName and className for a configuration option,
 *	return a string representation of the option.
 *
 * Results:
 *	Returns a Tk_Uid that is the string identifier that identifies
 *	Returns a Tcl_Obj* with the string identifier that identifies
 *	this option. Returns NULL if there are no system defaults
 *	that match this pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
Changes to macosx/tkMacOSXConstants.h.
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16








-
+







/*
 * 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
 * Copyright © 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
75
76
77
78
79
80
81



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98





99
100
101
102
103
104
105
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112







+
+
+




-












+
+
+
+
+







#define NSAlternateKeyMask NSEventModifierFlagOption
#define NSControlKeyMask NSEventModifierFlagControl
#define NSNumericPadKeyMask NSEventModifierFlagNumericPad
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSCursorUpdate NSEventTypeCursorUpdate
#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSCompositeCopy NSCompositingOperationCopy
#define NSCompositeSourceOver NSCompositingOperationSourceOver
#define NSCompositeSourceAtop NSCompositingOperationSourceAtop
#define NSCompositeDestinationIn NSCompositingOperationDestinationIn
#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
#define NSAlphaFirstBitmapFormat NSBitmapFormatAlphaFirst
#define NSAnyEventMask NSEventMaskAny
#define NSLeftMouseDownMask NSEventMaskLeftMouseDown
#define NSMouseMovedMask NSEventMaskMouseMoved
#define NSLeftMouseDraggedMask NSEventMaskLeftMouseDragged
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define NSStringPboardType NSPasteboardTypeString
#define NSOnState NSControlStateValueOn
#define NSOffState NSControlStateValueOff
#endif
Changes to macosx/tkMacOSXCursor.c.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * tkMacOSXCursor.c --
 *
 *	This file contains Macintosh specific cursor related routines.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 "tkMacOSXCursors.h"
183
184
185
186
187
188
189









190
191
192
193
194
195
196
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205







+
+
+
+
+
+
+
+
+








/*
 * 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);

258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281







-
+







		haveHotSpot = 1;
		break;
	    case IMAGEPATH:
		path = [NSApp tkFrameworkImagePath:cursorNames[idx].id1];
		break;
	    case IMAGEBITMAP: {
		unsigned char *bitmap = (unsigned char *)(cursorNames[idx].id1);
		NSBitmapImageRep *bitmapImageRep = NULL;
		NSBitmapImageRep *bitmapImageRep = nil;
		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);

453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
462
463
464
465
466
467
468

469
470
471
472
473
474
475
476







-
+







void
TkpFreeCursor(
    TkCursor *cursorPtr)
{
    TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr;

    [macCursorPtr->macCursor release];
    macCursorPtr->macCursor = NULL;
    macCursorPtr->macCursor = nil;
    if (macCursorPtr == gCurrentCursor) {
	gCurrentCursor = NULL;
    }
}

/*
 *----------------------------------------------------------------------
476
477
478
479
480
481
482
483

484
485

486
487
488
489
490


491

492
493
494
495
496
497
498
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







-
+

-
+





+
+
-
+







 *
 * Side effects:
 *	Changes the Macintosh mouse cursor.
 *
 *----------------------------------------------------------------------
 */

static void
void
TkMacOSXInstallCursor(
    void)
    int resizeOverride)
{
    TkMacOSXCursor *macCursorPtr = gCurrentCursor;
    static int cursorHidden = 0;
    int cursorNone = 0;

    gResizeOverride = resizeOverride;

    if (!macCursorPtr) {
    if (resizeOverride || !macCursorPtr) {
	[[NSCursor arrowCursor] set];
    } else {
	switch (macCursorPtr->type) {
	case NONE:
	    if (!cursorHidden) {
		cursorHidden = 1;
		[NSCursor hide];
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
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







+
+
+
+
-
+

















-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










void
TkpSetCursor(
    TkpCursor cursor)
{
    int cursorChanged = 1;

    if (!gTkOwnsCursor) {
	return;
    }

    if (cursor == None) {
    if (cursor == NULL) {
	/*
	 * 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();
	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/tkMacOSXCursors.h.
1
2
3
4
5
6
7
8
9



10
11
12
13
14
15
16
1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16






-
-
-
+
+
+







/*
 * tkMacOSXCursors.h --
 *
 *	This file defines a set of Macintosh cursor resources that
 *	are only available on the Macintosh platform.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright 2008-2009, Apple Inc.
 * Copyright (c) 2008-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2008-2009 Apple Inc.
 * Copyright © 2008-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.
 */

static const unsigned char tkMacOSXCursors[][68] = {

Changes to macosx/tkMacOSXDebug.c.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15






-
-
+
+







/*
 * tkMacOSXDebug.c --
 *
 *	Implementation of Macintosh specific functions for debugging MacOS
 *	events, regions, etc...
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 "tkMacOSXDebug.h"
Changes to macosx/tkMacOSXDebug.h.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15






-
-
+
+







/*
 * tkMacOSXDebug.h --
 *
 *	Declarations of Macintosh specific functions for debugging MacOS events,
 *	regions, etc...
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 _TKMACDEBUG
#define _TKMACDEBUG
Changes to macosx/tkMacOSXDefault.h.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17






-
-
-
-
+
+
+
+







/*
 * tkMacOSXDefault.h --
 *
 *	This file defines the defaults for all options for all of
 *	the Tk widgets.
 *
 * Copyright (c) 1991-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 © 1991-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 _TKMACDEFAULT
#define _TKMACDEFAULT
38
39
40
41
42
43
44
45

46
47
48


49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71



72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70


71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92




93

94




95

96
97
98
99
100
101
102







-
+


-
+
+








-
+












-
-
+
+
+




-
+














-
-
-
-

-

-
-
-
-

-







#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 INACTIVE_SELECT_BG	"systemUnemphasizedSelectedTextBackgroundColor"
#define TROUGH			"#c3c3c3"
#define INDICATOR		"#b03060"
#define DISABLED		"systemDisabledControlTextColor"
#define DISABLED		"#a3a3a3"
#define IGNORED                 "#abcdef"

/*
 * 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_BUTTON_ACTIVE_FG_COLOR	"systemPressedButtonTextColor"
#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_FG			BLACK
#define DEF_LABEL_FG			NORMAL_FG
#define DEF_CHKRAD_FG			DEF_LABEL_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_BUTTON_HIGHLIGHT		NORMAL_FG
#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
//#define DEF_BUTTON_PADX			"12"
//#define DEF_BUTTON_PADX_NOCM		"1"
//#else
#define DEF_BUTTON_PADX			"1"
//#endif
#define DEF_LABCHKRAD_PADX		"1"
//#if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS
//#define DEF_BUTTON_PADY			"3"
//#define DEF_BUTTON_PADY_NOCM		"1"
//#else
#define DEF_BUTTON_PADY			"1"
//#endif
#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
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135







-
+







#define DEF_CANVAS_BG_MONO		WHITE
#define DEF_CANVAS_BORDER_WIDTH		"0"
#define DEF_CANVAS_CLOSE_ENOUGH		"1"
#define DEF_CANVAS_CONFINE		"1"
#define DEF_CANVAS_CURSOR		""
#define DEF_CANVAS_HEIGHT		"7c"
#define DEF_CANVAS_HIGHLIGHT_BG		NORMAL_BG
#define DEF_CANVAS_HIGHLIGHT		BLACK
#define DEF_CANVAS_HIGHLIGHT		NORMAL_FG
#define DEF_CANVAS_HIGHLIGHT_WIDTH	"3"
#define DEF_CANVAS_INSERT_BG		BLACK
#define DEF_CANVAS_INSERT_BD_COLOR	"0"
#define DEF_CANVAS_INSERT_BD_MONO	"0"
#define DEF_CANVAS_INSERT_OFF_TIME	"300"
#define DEF_CANVAS_INSERT_ON_TIME	"600"
#define DEF_CANVAS_INSERT_WIDTH		"2"
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186


187
188
189
190
191
192
193







-
+








-
-







#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		NORMAL_FG
#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"
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
201
202
203
204
205
206
207

208

209
210
211
212
213
214
215

216
217
218
219
220
221
222
223







-

-







-
+







#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
#define DEF_FRAME_HIGHLIGHT		BLACK
#define DEF_FRAME_HIGHLIGHT		NORMAL_FG
#define DEF_FRAME_HIGHLIGHT_WIDTH	"0"
#define DEF_FRAME_PADX			"0"
#define DEF_FRAME_PADY			"0"
#define DEF_FRAME_RELIEF		"flat"
#define DEF_FRAME_TAKE_FOCUS		"0"
#define DEF_FRAME_VISUAL		""
#define DEF_FRAME_WIDTH			"0"
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259







-
+







#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		NORMAL_FG
#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
307
308
309
310
311
312
313
314
315


316
317
318


319
320
321


322
323
324
325


326
327

328
329
330
331


332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348






349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
295
296
297
298
299
300
301


302
303
304


305
306



307
308
309
310


311
312
313

314
315
316


317
318
319
320
321
322
323
324
325
326
327
328
329






330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
-
+
+

-
-
+
+
-
-
-
+
+


-
-
+
+

-
+


-
-
+
+











-
-
-
-
-
-
+
+
+
+
+
+











-
+







#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_BG_COLOR	IGNORED
#define DEF_MENU_ACTIVE_BG_MONO		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_FG_COLOR	IGNORED
#define DEF_MENU_ACTIVE_FG_MONO		IGNORED
#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_BG_COLOR		"#000001" /* Detects custom bg. */
#define DEF_MENU_BG_MONO		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_DISABLED_FG_COLOR	IGNORED
#define DEF_MENU_DISABLED_FG_MONO	""
#define DEF_MENU_FONT			"menu" /* special: see tkMacOSXMenu.c */
#define DEF_MENU_FG			NORMAL_FG
#define DEF_MENU_FG			"#010000"  /* Detects custom 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_SELECT_COLOR		IGNORED
#define DEF_MENU_SELECT_MONO		IGNORED
#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_ACTIVE_BG_COLOR	ACTIVE_BG
#define DEF_MENUBUTTON_ACTIVE_BG_MONO	WHITE
#define DEF_MENUBUTTON_ACTIVE_FG_COLOR	ACTIVE_FG
#define DEF_MENUBUTTON_ACTIVE_FG_MONO	BLACK
#define DEF_MENUBUTTON_BG_COLOR		NORMAL_BG
#define DEF_MENUBUTTON_BG_MONO		WHITE
#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	NORMAL_FG
#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"
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384







-
+







#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		NORMAL_FG
#define DEF_MESSAGE_HIGHLIGHT_WIDTH	"0"
#define DEF_MESSAGE_JUSTIFY		"left"
#define DEF_MESSAGE_PADX		"-1"
#define DEF_MESSAGE_PADY		"-1"
#define DEF_MESSAGE_RELIEF		"flat"
#define DEF_MESSAGE_TAKE_FOCUS		"0"
#define DEF_MESSAGE_TEXT		""
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450







-
+







#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		NORMAL_FG
#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"
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
471
472
473
474
475
476
477

478
479
480
481
482
483
484
485







-
+







#define DEF_SCROLLBAR_BG_COLOR		NORMAL_BG
#define DEF_SCROLLBAR_BG_MONO		WHITE
#define DEF_SCROLLBAR_BORDER_WIDTH	"0"
#define DEF_SCROLLBAR_COMMAND		""
#define DEF_SCROLLBAR_CURSOR		""
#define DEF_SCROLLBAR_EL_BORDER_WIDTH	"-1"
#define DEF_SCROLLBAR_HIGHLIGHT_BG	NORMAL_BG
#define DEF_SCROLLBAR_HIGHLIGHT		BLACK
#define DEF_SCROLLBAR_HIGHLIGHT		NORMAL_FG
#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
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
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_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		NORMAL_FG
#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_INACTIVE_SELECT_BG_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"
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
1
2
3
4
5




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59





-
-
-
-
+
+
+
+
+
















-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/*
 * 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.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2017 Christian Gollwitzer
 * Copyright © 2022 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 "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 modalOther  -1 // indicates that the -command option was used.
#define modalError  -2

static void setAllowedFileTypes(
    NSSavePanel *panel,
    NSMutableArray *extensions)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
/* UTType exists in the SDK */
    if (@available(macOS 11.0, *)) {
	NSMutableArray<UTType *> *allowedTypes = [NSMutableArray array];
	for (NSString *ext in extensions) {
	    UTType *uttype = [UTType typeWithFilenameExtension: ext];
	    [allowedTypes addObject:uttype];
	}
	[panel setAllowedContentTypes:allowedTypes];
    } else {
# if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
/* setAllowedFileTypes is not deprecated */
	[panel setAllowedFileTypes:extensions];
#endif
    }
#else
    [panel setAllowedFileTypes:extensions];
#endif
}

/*
 * Vars for filtering in "open file" and "save file" dialogs.
 */

typedef struct {
    bool doFileTypes;			/* Show the accessory view which
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142







-
+













-
+







};
static const char *const chooseOptionStrings[] = {
    "-initialdir", "-message", "-mustexist", "-parent", "-title", "-command",
    NULL
};
enum chooseOptions {
    CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST, CHOOSE_PARENT,
    CHOOSE_TITLE, CHOOSE_COMMAND,
    CHOOSE_TITLE, CHOOSE_COMMAND
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int multiple;
} FilePanelCallbackInfo;

static const char *const alertOptionStrings[] = {
    "-default", "-detail", "-icon", "-message", "-parent", "-title",
    "-type", "-command", NULL
};
enum alertOptions {
    ALERT_DEFAULT, ALERT_DETAIL, ALERT_ICON, ALERT_MESSAGE, ALERT_PARENT,
    ALERT_TITLE, ALERT_TYPE, ALERT_COMMAND,
    ALERT_TITLE, ALERT_TYPE, ALERT_COMMAND
};
typedef struct {
    Tcl_Interp *interp;
    Tcl_Obj *cmdObj;
    int typeIndex;
} AlertCallbackInfo;
static const char *const alertTypeStrings[] = {
215
216
217
218
219
220
221
222

223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269

270
271
272
273
274
275
276
277

278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316

317
318
319
320

321
322
323
324
325
326
327
328
329

330
331
332
333

334
335
336
337

338
339
340
341
342
343
344
345
346
347
348
349
350

351


352
353






354
355

356
357
358
359
360
361
362







363
364
365
366
367
368





369
370

371

372
373

374

375
376
377





378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





395
396

397
398

399
400
401
402
403
404
405
240
241
242
243
244
245
246

247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282






283
284
285
286

287
288

289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316




317
318
319
320

321

322
323
324
325
326
327
328
329
330
331

332
333
334
335

336
337
338
339
340
341
342
343
344

345
346
347
348

349
350
351
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375
376
377
378
379
380







381
382
383
384
385
386
387






388
389
390
391
392


393

394
395
396
397

398



399
400
401
402
403

















404
405
406
407
408


409


410
411
412
413
414
415
416
417







-
+

-
+















+
-
+
















-
-
-
-
-
-




-
+

-
+








+
-
+

















-
-
-
-




-
+
-










-
+



-
+








-
+



-
+



-
+













+
-
+
+


+
+
+
+
+
+


+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
+
-
+


+
-
+
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
-
-
+







    (void)sender; (void)url;
    *outError = nil;
    return YES;
}

- (void) tkFilePanelDidEnd: (NSSavePanel *) panel
		returnCode: (NSModalResponse) returnCode
	       contextInfo: (void *) contextInfo
	       contextInfo: (const void *) contextInfo
{
    FilePanelCallbackInfo *callbackInfo = contextInfo;
    const FilePanelCallbackInfo *callbackInfo = (const FilePanelCallbackInfo *)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;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
	    int 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
	contextInfo: (const void *) contextInfo
{
    AlertCallbackInfo *callbackInfo = contextInfo;
    AlertCallbackInfo *callbackInfo = (AlertCallbackInfo *)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;
	    int objc, result = Tcl_ListObjGetElements(callbackInfo->interp,
	    int 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];
    filterInfo.fileTypeIndex   = (NSUInteger)[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];
	setAllowedFileTypes(openpanel, nil);
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	[openpanel setAllowedFileTypes:allowedtypes];
	setAllowedFileTypes(openpanel, allowedtypes);
	[openpanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

- (void)saveFormat:(id)sender  {
    NSPopUpButton *button     = (NSPopUpButton *)sender;
    filterInfo.fileTypeIndex  = [button indexOfSelectedItem];
    filterInfo.fileTypeIndex  = (NSUInteger)[button indexOfSelectedItem];

    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
	[savepanel setAllowsOtherFileTypes:YES];
	[savepanel setAllowedFileTypes:nil];
	setAllowedFileTypes(savepanel, nil);
    } else {
	NSMutableArray *allowedtypes =
		[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
	[savepanel setAllowedFileTypes:allowedtypes];
	setAllowedFileTypes(savepanel, allowedtypes);
	[savepanel setAllowsOtherFileTypes:NO];
    }

    filterInfo.userHasSelectedFilter = true;
}

@end

#pragma mark -

static NSInteger showOpenSavePanel(
    NSSavePanel *panel,
    NSWindow *parent,
    Tcl_Interp *interp,
    FilePanelCallbackInfo *callbackInfo)
    Tcl_Obj *cmdObj,
    int multiple)
{
    NSInteger modalReturnCode;
    int OSVersion = [NSApp macOSVersion];
    const FilePanelCallbackInfo callbackInfo = {interp, cmdObj, multiple};

    /*
     * Use a sheet if -parent is specified (unless there is already a sheet).
     */

    if (parent && ![parent attachedSheet]) {
	if (OSVersion < 101500) {
	[panel beginSheetModalForWindow:parent
	       completionHandler:^(NSModalResponse returnCode) {
	    [NSApp tkFilePanelDidEnd:panel
		       returnCode:returnCode
		       contextInfo:callbackInfo ];
	    }];

	    [panel beginSheetModalForWindow:parent
			  completionHandler:^(NSModalResponse returnCode) {
		    [NSApp tkFilePanelDidEnd:panel
				  returnCode:returnCode
				 contextInfo:&callbackInfo ];
		}];
	    modalReturnCode = [NSApp runModalForWindow:panel];
	/*
	 * 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.
	} else if (OSVersion < 110000) {
	    [panel beginSheetModalForWindow:parent
			  completionHandler:^(NSModalResponse returnCode) {
		    [NSApp tkFilePanelDidEnd:panel
				  returnCode:returnCode
	 */

				 contextInfo:&callbackInfo ];
	if ([NSApp macOSVersion] > 101400) {
		}];
	    modalReturnCode = [panel runModal];
	} else {
	    [parent beginSheet: panel completionHandler:nil];
	    modalReturnCode = [NSApp runModalForWindow:panel];
	    modalReturnCode = [panel runModal];
	}
    } else {

	    [NSApp tkFilePanelDidEnd:panel
			  returnCode:modalReturnCode
			 contextInfo:&callbackInfo ];
	    [parent endSheet:panel];
	}
	/* 
	 * 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 ];
    } else {
	modalReturnCode = [panel runModal];
	[NSApp tkFilePanelDidEnd:panel
		      returnCode:modalReturnCode
		     contextInfo:&callbackInfo ];
	    [panel close];
	}
    }
    }
    return callbackInfo->cmdObj ? modalOther : modalReturnCode;
    return cmdObj ? modalOther : modalReturnCode;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445







-
+







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. */
{
    int result = TCL_ERROR;
    Tk_Window parent, tkwin = clientData;
    Tk_Window parent, tkwin = (Tk_Window)clientData;
    const char *title = NULL;
    int i;
    NSColor *color = nil, *initialColor = nil;
    NSColorPanel *colorPanel;
    NSInteger returnCode, numberOfComponents = 0;

    for (i = 1; i < objc; i += 2) {
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472







-
+







	}
	value = Tcl_GetString(objv[i + 1]);

	switch (index) {
	case COLOR_INITIAL: {
	    XColor *colorPtr;

	    colorPtr = Tk_GetColor(interp, tkwin, value);
	    colorPtr = Tk_AllocColorFromObj(interp, tkwin, objv[i + 1]);
	    if (colorPtr == NULL) {
		goto end;
	    }
	    initialColor = TkMacOSXGetNSColor(NULL, colorPtr->pixel);
	    Tk_FreeColor(colorPtr);
	    break;
	}
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498







-
+







    colorPanel = [NSColorPanel sharedColorPanel];
    [colorPanel orderOut:NSApp];
    [colorPanel setContinuous:NO];
    [colorPanel setBecomesKeyOnlyIfNeeded:NO];
    [colorPanel setShowsAlpha: NO];
    [colorPanel _setUseModalAppearance:YES];
    if (title) {
	NSString *s = [[NSString alloc] initWithUTF8String:title];
	NSString *s = [[TKNSString alloc] initWithTclUtfBytes:title length:-1];

	[colorPanel setTitle:s];
	[s release];
    }
    if (initialColor) {
	[colorPanel setColor:initialColor];
    }
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
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







-
+

















-
+








    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];
	    NSString *name = [[TKNSString alloc] initWithTclUtfBytes: filterPtr->name length:-1];

	    [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];
			NSString *extension = [[TKNSString alloc] initWithTclUtfBytes:str length:-1];
			if (![filterInfo.allowedExtensions containsObject:extension]) {
			    [filterInfo.allowedExtensions addObject:extension];
			}

			[clauseextensions addObject:extension];
			[displayextensions addObject:[@"." stringByAppendingString:extension]];

615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
627
628
629
630
631
632
633

634
635
636
637
638
639
640
641







-
+







	     * Check that the typevariable exists.
	     */

	    if (selectedFileTypeObj != NULL) {
		const char *selectedFileType =
			Tcl_GetString(selectedFileTypeObj);
		NSString *selectedFileTypeStr =
			[[NSString alloc] initWithUTF8String:selectedFileType];
			[[TKNSString alloc] initWithTclUtfBytes:selectedFileType length:-1];
		NSUInteger index =
			[filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr];

		if (index != NSNotFound) {
		    filterInfo.fileTypeIndex = index;
		    filterInfo.preselectFilter = true;
		}
674
675
676
677
678
679
680
681

682
683
684


685
686
687
688
689
690
691
692
693
694
686
687
688
689
690
691
692

693
694
695

696
697
698


699
700
701
702
703
704
705







-
+


-
+
+

-
-







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. */
{
    Tk_Window tkwin = clientData;
    Tk_Window tkwin = (Tk_Window)clientData;
    char *str;
    int i, result = TCL_ERROR, haveParentOption = 0;
    int index, len, multiple = 0;
    int index, multiple = 0;
    int len;
    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;

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
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







-
+






-
+




+
-
+
-
+
















+
-
+
-
+







	    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]
		directory = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			autorelease];
	    }
	    break;
	case OPEN_INITFILE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		filename = [[[NSString alloc] initWithUTF8String:str]
		filename = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			autorelease];
	    }
	    break;
	case OPEN_MESSAGE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    message = [[NSString alloc] initWithUTF8String:
	    message = [[TKNSString alloc] initWithTclUtfBytes:
		    Tcl_GetString(objv[i + 1])];
		    str length:len];
	    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:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    title = [[NSString alloc] initWithUTF8String:
	    title = [[TKNSString alloc] initWithTclUtfBytes:
		    Tcl_GetString(objv[i + 1])];
		    str length:len];
	    break;
	case OPEN_TYPEVARIABLE:
	    typeVariablePtr = objv[i + 1];
	    break;
	case OPEN_COMMAND:
	    cmdObj = objv[i+1];
	    break;
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
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







-
+



















+










-
+







-
+

-
+




















-
-
-
-












-
+
+
+
+







    }

    if (message) {
	[openpanel setMessage:message];
	[message release];
    }

    [openpanel setAllowsMultipleSelection:multiple];
    [openpanel setAllowsMultipleSelection:multiple != 0];

    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 setTarget:NSApp];
	[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];
	    [popupButton selectItemAtIndex:(NSInteger)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];
	    setAllowedFileTypes(openpanel, filterInfo.allowedExtensions);
	} else {
	    [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
	    setAllowedFileTypes(openpanel, 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);
    modalReturnCode = showOpenSavePanel(openpanel, parent, interp, cmdObj, multiple);
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
    if ((typeVariablePtr && (modalReturnCode == NSOKButton))
	    && filterInfo.doFileTypes) {
	/*
949
950
951
952
953
954
955
956


957
958
959
960
961
962
963
964
965
966
962
963
964
965
966
967
968

969
970
971


972
973
974
975
976
977
978







-
+
+

-
-







    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;
    int index;
    int 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;

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
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







-
+


-
+









-
+






-
+





+
-
+
-
+










+
-
+
-
+







	    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++;
		    str++; len--;
		}
		if (*str) {
		    defaultType = [[[NSString alloc] initWithUTF8String:str]
		    defaultType = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			    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]
		    directory = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			    autorelease];
		}
		break;
	    case SAVE_INITFILE:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		if (len) {
		    filename = [[[NSString alloc] initWithUTF8String:str]
		    filename = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			    autorelease];
		    [savepanel setNameFieldStringValue:filename];
		}
		break;
	    case SAVE_MESSAGE:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		message = [[NSString alloc] initWithUTF8String:
		message = [[TKNSString alloc] initWithTclUtfBytes:
			Tcl_GetString(objv[i + 1])];
			str length:len];
		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:
		str = Tcl_GetStringFromObj(objv[i + 1], &len);
		title = [[NSString alloc] initWithUTF8String:
		title = [[TKNSString alloc] initWithTclUtfBytes:
			Tcl_GetString(objv[i + 1])];
			str length:len];
		break;
	    case SAVE_TYPEVARIABLE:
		typeVariablePtr = objv[i + 1];
		break;
	    case SAVE_COMMAND:
		cmdObj = objv[i+1];
		break;
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
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







-
+
+

-





+
-
+











-
+












-
-
-
-







	[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 selectItemAtIndex:(NSInteger)filterInfo.fileTypeIndex];
	[popupButton setTarget:NSApp];
	[popupButton setAction:@selector(saveFormat:)];

	[accessoryView addSubview:label];
	[accessoryView addSubview:popupButton];

	[savepanel setAccessoryView:accessoryView];

	setAllowedFileTypes(savepanel,
	[savepanel setAllowedFileTypes:[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]];
	    [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];
	setAllowedFileTypes(savepanel, 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
1138
1139
1140
1141
1142
1143
1144
1145




1146
1147
1148
1149
1150
1151
1152
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166







-
+
+
+
+







    if (haveParentOption) {
	parent = TkMacOSXGetNSWindowForDrawable(((TkWindow *)tkwin)->window);
	parentIsKey = parent && [parent isKeyWindow];
    } else {
	parent = nil;
	parentIsKey = False;
    }
    modalReturnCode = showOpenSavePanel(savepanel, parent, callbackInfo);
    modalReturnCode = showOpenSavePanel(savepanel, parent, interp, cmdObj, 0);
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }

    if (typeVariablePtr && (modalReturnCode == NSOKButton)
	    && filterInfo.doFileTypes) {
1190
1191
1192
1193
1194
1195
1196
1197


1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1204
1205
1206
1207
1208
1209
1210

1211
1212
1213


1214
1215
1216
1217
1218
1219
1220







-
+
+

-
-







    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;
    int index, mustexist = 0;
    int len;
    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;

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
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







-
+




+
-
+
-
+


















+
-
+
-
+


















-
-
-
-


















-
+
+
+
+







	    Tcl_SetErrorCode(interp, "TK", "DIRDIALOG", "VALUE", NULL);
	    goto end;
	}
	switch (index) {
	case CHOOSE_INITDIR:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    if (len) {
		directory = [[[NSString alloc] initWithUTF8String:str]
		directory = [[[TKNSString alloc] initWithTclUtfBytes:str length:len]
			autorelease];
	    }
	    break;
	case CHOOSE_MESSAGE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    message = [[NSString alloc] initWithUTF8String:
	    message = [[TKNSString alloc] initWithTclUtfBytes:
		    Tcl_GetString(objv[i + 1])];
		    str length:len];
	    [panel setMessage:message];
	    [message release];
	    break;
	case CHOOSE_MUSTEXIST:
	    if (Tcl_GetBooleanFromObj(interp, objv[i + 1],
		    &mustexist) != TCL_OK) {
		goto end;
	    }
	    break;
	case CHOOSE_PARENT:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;
	case CHOOSE_TITLE:
	    str = Tcl_GetStringFromObj(objv[i + 1], &len);
	    title = [[NSString alloc] initWithUTF8String:
	    title = [[TKNSString alloc] initWithTclUtfBytes:
		    Tcl_GetString(objv[i + 1])];
		    str length:len];
	    [panel setTitle:title];
	    [title release];
	    break;
	case CHOOSE_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
    }
    [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);
    modalReturnCode = showOpenSavePanel(panel, parent, interp, cmdObj, 0);
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
    if (parentIsKey) {
	[parent makeKeyWindow];
    }
  end:
    return result;
}
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
1325
1326
1327
1328
1329
1330
1331



1332





1333
1334

















































1335
1336
1337
1338
1339
1340
1341







-
-
-
+
-
-
-
-
-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







 *
 *----------------------------------------------------------------------
 */

void
TkAboutDlg(void)
{
    NSImage *image;
    NSString *path = [NSApp tkFrameworkImagePath: @"Tk.tiff"];

    [NSApp orderFrontStandardAboutPanel:nil];
    if (path) {
	image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
    } else {
	image = [NSApp applicationIconImage];
    }
}

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [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.
 *
1396
1397
1398
1399
1400
1401
1402
1403

1404
1405
1406
1407
1408
1409
1410
1355
1356
1357
1358
1359
1360
1361

1362
1363
1364
1365
1366
1367
1368
1369







-
+







    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    TkAboutDlg();
    [NSApp orderFrontStandardAboutPanel:nil];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --
1429
1430
1431
1432
1433
1434
1435
1436

1437
1438
1439
1440
1441
1442
1443
1388
1389
1390
1391
1392
1393
1394

1395
1396
1397
1398
1399
1400
1401
1402







-
+







{
    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;
    AlertCallbackInfo callbackInfo;
    NSString *message, *title;
    NSWindow *parent;
    NSArray *buttons;
    NSAlert *alert = [NSAlert new];
    NSInteger modalReturnCode = 1;
    BOOL parentIsKey = NO;

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
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







-
-
+
+
+












-
-
+
+
+














-
-
+
+
+







	     * know the '-type' as well.
	     */

	    indexDefaultOption = i;
	    break;

	case ALERT_DETAIL:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    str = Tcl_GetString(objv[i + 1]);
	    message = [[TKNSString alloc] initWithTclUtfBytes:
		    str length:-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])];
	    str = Tcl_GetString(objv[i + 1]);
	    message = [[TKNSString alloc] initWithTclUtfBytes:
		    str length:-1];
	    [alert setMessageText:message];
	    [message release];
	    break;

	case ALERT_PARENT:
	    str = Tcl_GetString(objv[i + 1]);
	    tkwin = Tk_NameToWindow(interp, str, tkwin);
	    if (!tkwin) {
		goto end;
	    }
	    haveParentOption = 1;
	    break;

	case ALERT_TITLE:
	    title = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
	    str = Tcl_GetString(objv[i + 1]);
	    title = [[TKNSString alloc] initWithTclUtfBytes:
		    str length:-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) {
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
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







-
+







-
-
-
-
+
+
+








-
+





-
+






-
+
+
+
+


















-
+








	if (([ke isEqualToString:@"\r"] || [ke isEqualToString:@"\033"]) &&
		![b keyEquivalentModifierMask]) {
	    [b setKeyEquivalent:@""];
	}
    }
    [[buttons objectAtIndex: [buttons count]-1] setKeyEquivalent: @"\033"];
    [[buttons objectAtIndex: defaultNativeButtonIndex-1]
    [[buttons objectAtIndex: (NSUInteger)(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;
    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];
		    contextInfo:&callbackInfo];
	}];
#else
	[alert beginSheetModalForWindow:parent
	       modalDelegate:NSApp
	       didEndSelector:@selector(tkAlertDidEnd:returnCode:contextInfo:)
	       contextInfo:callbackInfo];
	       contextInfo:&callbackInfo];
#endif
	modalReturnCode = cmdObj ? 0 :
	    [alert runModal];
    } else {
	modalReturnCode = [alert runModal];
	[NSApp tkAlertDidEnd:alert returnCode:modalReturnCode
		contextInfo:callbackInfo];
		contextInfo:&callbackInfo];
    }
    if (cmdObj) {
	Tcl_DecrRefCount(cmdObj);
    }
    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 "tkMacOSXEvent.h"
#include "tkMacOSXFont.h"

typedef struct FontchooserData {
    Tcl_Obj *titleObj;
    Tcl_Obj *cmdObj;
    Tk_Window parent;
} FontchooserData;
1694
1695
1696
1697
1698
1699
1700
1701

1702
1703
1704
1705
1706
1707
1708
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671
1672







-
+







	    NSFontPanelUnderlineEffectModeMask |
	    NSFontPanelStrikethroughEffectModeMask;
}

- (void) windowDidOrderOffScreen: (NSNotification *)notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if ([[notification object] isEqual:[[NSFontManager sharedFontManager]
	    fontPanel:NO]]) {
	FontchooserEvent(FontchooserClosed);
    }
}
@end
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
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







-
+


-
-
+
+








-
+
+













-
+







{
    FontchooserData *fcdPtr;
    Tcl_Obj *fontObj;

    if (!fontchooserInterp) {
	return;
    }
    fcdPtr = Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
    fcdPtr = (FontchooserData *)Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
    switch (kind) {
    case FontchooserClosed:
	if (fcdPtr->parent != None) {
	    Tk_SendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	if (fcdPtr->parent != NULL) {
	    TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
	    fontchooserInterp = NULL;
	}
	break;
    case FontchooserSelection:
	fontObj = TkMacOSXFontDescriptionForNSFontAndNSFontAttributes(
		fontPanelFont, fontPanelFontAttributes);
	if (fontObj) {
	    if (fcdPtr->cmdObj) {
		int objc, result;
		int objc;
		int 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);
	    TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL);
	}
	break;
    }
}

/*
 *----------------------------------------------------------------------
1789
1790
1791
1792
1793
1794
1795
1796

1797
1798
1799
1800
1801
1802
1803
1754
1755
1756
1757
1758
1759
1760

1761
1762
1763
1764
1765
1766
1767
1768







-
+







    FontchooserData *fcdPtr,
    int optionIndex)
{
    Tcl_Obj *resObj = NULL;

    switch(optionIndex) {
    case FontchooserParent:
	if (fcdPtr->parent != None) {
	if (fcdPtr->parent != NULL) {
	    resObj = Tcl_NewStringObj(
		    ((TkWindow *)fcdPtr->parent)->pathName, -1);
	} else {
	    resObj = Tcl_NewStringObj(".", 1);
	}
	break;
    case FontchooserTitle:
1818
1819
1820
1821
1822
1823
1824
1825
1826


1827
1828
1829
1830
1831
1832
1833
1783
1784
1785
1786
1787
1788
1789


1790
1791
1792
1793
1794
1795
1796
1797
1798







-
-
+
+







	if (fcdPtr->cmdObj) {
	    resObj = fcdPtr->cmdObj;
	} else {
	    resObj = Tcl_NewObj();
	}
	break;
    case FontchooserVisible:
	resObj = Tcl_NewWideIntObj([[[NSFontManager sharedFontManager]
		fontPanel:NO] isVisible] != 0);
	resObj = Tcl_NewBooleanObj([[[NSFontManager sharedFontManager]
		fontPanel:NO] isVisible]);
	break;
    default:
	resObj = Tcl_NewObj();
    }
    return resObj;
}

1852
1853
1854
1855
1856
1857
1858
1859

1860

1861

1862
1863
1864
1865
1866
1867
1868
1817
1818
1819
1820
1821
1822
1823

1824
1825
1826

1827
1828
1829
1830
1831
1832
1833
1834







-
+

+
-
+







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",
    FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);
    int i;
    int i, r = TCL_OK;
    int r = TCL_OK;

    /*
     * With no arguments we return all the options in a dict
     */

    if (objc == 1) {
	Tcl_Obj *keyObj, *valueObj;
1876
1877
1878
1879
1880
1881
1882
1883


1884
1885
1886
1887
1888
1889
1890
1842
1843
1844
1845
1846
1847
1848

1849
1850
1851
1852
1853
1854
1855
1856
1857







-
+
+







	if (r == TCL_OK) {
	    Tcl_SetObjResult(interp, dictObj);
	}
	return r;
    }

    for (i = 1; i < objc; i += 2) {
	int optionIndex, len;
	int optionIndex;
	int len;

	if (Tcl_GetIndexFromObjStruct(interp, objv[i], fontchooserOptionStrings,
		sizeof(char *), "option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*
1909
1910
1911
1912
1913
1914
1915
1916

1917
1918
1919
1920
1921
1922
1923
1876
1877
1878
1879
1880
1881
1882

1883
1884
1885
1886
1887
1888
1889
1890







-
+







	    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) {
	    if (parent == NULL) {
		return TCL_ERROR;
	    }
	    if (fcdPtr->parent) {
		Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
			FontchooserParentEventHandler, fcdPtr);
	    }
	    fcdPtr->parent = parent;
1936
1937
1938
1939
1940
1941
1942
1943

1944
1945
1946
1947
1948
1949
1950
1903
1904
1905
1906
1907
1908
1909

1910
1911
1912
1913
1914
1915
1916
1917







-
+







		    fcdPtr->titleObj = Tcl_DuplicateObj(fcdPtr->titleObj);
		}
		Tcl_IncrRefCount(fcdPtr->titleObj);
	    } else {
		fcdPtr->titleObj = NULL;
	    }
	    break;
	case FontchooserFont:
	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;
		}
1966
1967
1968
1969
1970
1971
1972
1973

1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
1933
1934
1935
1936
1937
1938
1939

1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951







-
+



+







	    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,
		TkSendVirtualEvent(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];
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
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







-
+


-
+













-
+







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",
    FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
	    NULL);

    if (fcdPtr->parent == None) {
    if (fcdPtr->parent == NULL) {
	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);
	TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
    }
    fontchooserInterp = interp;

    return TCL_OK;
}

/*
2093
2094
2095
2096
2097
2098
2099
2100

2101
2102
2103
2104
2105
2106
2107
2061
2062
2063
2064
2065
2066
2067

2068
2069
2070
2071
2072
2073
2074
2075







-
+







 */

static void
FontchooserParentEventHandler(
    ClientData clientData,
    XEvent *eventPtr)
{
    FontchooserData *fcdPtr = clientData;
    FontchooserData *fcdPtr = (FontchooserData *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
		FontchooserParentEventHandler, fcdPtr);
	fcdPtr->parent = NULL;
	FontchooserHideCmd(NULL, NULL, 0, NULL);
    }
2125
2126
2127
2128
2129
2130
2131
2132

2133
2134
2135
2136
2137
2138
2139
2093
2094
2095
2096
2097
2098
2099

2100
2101
2102
2103
2104
2105
2106
2107







-
+







 */

static void
DeleteFontchooserData(
    ClientData clientData,
    Tcl_Interp *interp)
{
    FontchooserData *fcdPtr = clientData;
    FontchooserData *fcdPtr = (FontchooserData *)clientData;

    if (fcdPtr->titleObj) {
	Tcl_DecrRefCount(fcdPtr->titleObj);
    }
    if (fcdPtr->cmdObj) {
	Tcl_DecrRefCount(fcdPtr->cmdObj);
    }
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
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37






-
-
-
-
+
+
+
+



















+







/*
 * 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.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 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
#define TK_MAC_DEBUG_CG
#endif
*/

#define radians(d)	((d) * (M_PI/180.0))

/*
 * Non-antialiased CG drawing looks better and more like X11 drawing when using
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143







-
+







    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap;
    NSImage *nsImage;
    if (width == 0 || height == 0) {
    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);

170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185







-
+







    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);
    XCopyPlane(display, bitmap, pixmap, gc, 0, 0, (unsigned)width, (unsigned)height, 0, 0, 1);
    gc->background = origBackground;
    nsImage = CreateNSImageFromPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}

222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238
239
240
241
242
243


244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276


277
278
279
280
281
282
283
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238
239
240
241
242


243
244
245
246
247
248
249
250

251
252
253
254
255
256
257

258
259
260
261

262
263
264

265
266







267
268
269
270
271
272
273
274
275







-
+












-
-
+
+






-







-




-



-


-
-
-
-
-
-
-
+
+








    return nsImage;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MacOSXGetCGContextForDrawable --
 * TkMacOSXGetCGContextForDrawable --
 *
 *	Get CGContext for given Drawable, creating one if necessary.
 *
 * Results:
 *	CGContext.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
Tk_MacOSXGetCGContextForDrawable(
CGContextRef
TkMacOSXGetCGContextForDrawable(
    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,
	macDraw->context = CGBitmapContextCreate(NULL, (unsigned)macDraw->size.width,
		(unsigned)macDraw->size.height, bitsPerComponent, 0,
		colorspace, bitmapInfo);
	if (macDraw->context) {
	    CGContextClearRect(macDraw->context, bounds);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
414
415
416
417
418
419
420
421

422
423
424
425
426
427
428
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420







-
+







    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    if (npoints < 2) {
	return BadValue;
    }

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (lw % 2) ? .5 : 0;

482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
474
475
476
477
478
479
480

481
482
483
484
485
486
487
488







-
+







    XSegment *segments,
    int nsegments)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i, lw = gc->line_width;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double o = (lw % 2) ? .5 : 0;

	for (i = 0; i < nsegments; i++) {
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541

542
543
544
545
546
547
548
519
520
521
522
523
524
525

526
527
528
529
530
531
532

533
534
535
536
537
538
539
540







-
+






-
+







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. */
    TCL_UNUSED(int),		/* Shape to draw. */
    int mode)			/* Drawing mode. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    int i;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	double prevx, prevy;
	double o = (gc->line_width % 2) ? .5 : 0;

557
558
559
560
561
562
563

564


565
566
567
568
569
570
571
549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564
565







+
-
+
+







			macWin->yOff + points[i].y + o);
	    } else {
		prevx += points[i].x;
		prevy += points[i].y;
		CGContextAddLineToPoint(dc.context, prevx, prevy);
	    }
	}
	(gc->fill_rule == EvenOddRule)
	CGContextEOFillPath(dc.context);
		? CGContextEOFillPath(dc.context)
		: CGContextFillPath(dc.context);
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

/*
 *----------------------------------------------------------------------
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
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







-
+
















+







    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0) {
	return BadDrawable;
    }

    display->request++;
    LastKnownRequestProcessed(display)++;
    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;
}

#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:
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659







-
+







    int nRects)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i, lw = gc->line_width;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

672
673
674
675
676
677
678

679
680
681
682
683
684
685
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681







+







		    rectPtr->width, rectPtr->height);
	    CGContextStrokeRect(dc.context, rect);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XFillRectangles --
 *
 *	Fill multiple rectangular areas in the given drawable.
702
703
704
705
706
707
708
709

710
711
712
713
714
715
716
698
699
700
701
702
703
704

705
706
707
708
709
710
711
712







-
+







    int n_rectangles)		/* Number of rectangles. */
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XRectangle * rectPtr;
    int i;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;

	for (i = 0, rectPtr = rectangles; i < n_rectangles; i++, rectPtr++) {
807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
803
804
805
806
807
808
809

810
811
812
813
814
815
816
817







-
+







    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

842
843
844
845
846
847
848

849
850
851
852
853
854
855
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852







+







	    CGContextStrokePath(dc.context);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

#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
877
878
879
880
881
882
883
884

885
886
887
888
889
890
891
874
875
876
877
878
879
880

881
882
883
884
885
886
887
888







-
+







    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc *arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0;

922
923
924
925
926
927
928

929
930
931
932
933
934
935
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933







+







		CGContextStrokePath(dc.context);
	    }
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XFillArc --
 *
 *	Draw a filled arc.
958
959
960
961
962
963
964
965

966
967
968
969
970
971
972
956
957
958
959
960
961
962

963
964
965
966
967
968
969
970







-
+







    TkMacOSXDrawingContext dc;
    int lw = gc->line_width;

    if (width == 0 || height == 0 || angle2 == 0) {
	return BadDrawable;
    }

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014







+







	    CGContextFillPath(dc.context);
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}

#ifdef TK_MACOSXDRAW_UNUSED
/*
 *----------------------------------------------------------------------
 *
 * XFillArcs --
 *
 *	Draw a filled arc.
 *
1031
1032
1033
1034
1035
1036
1037
1038

1039
1040
1041
1042
1043
1044
1045
1030
1031
1032
1033
1034
1035
1036

1037
1038
1039
1040
1041
1042
1043
1044







-
+







    int nArcs)
{
    MacDrawable *macWin = (MacDrawable *)d;
    TkMacOSXDrawingContext dc;
    XArc * arcPtr;
    int i, lw = gc->line_width;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(d, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect rect;
	double o = (lw % 2) ? .5 : 0, u = 0;

1083
1084
1085
1086
1087
1088
1089


















1090
1091
1092
1093
1094
1095
1096
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		CGContextFillPath(dc.context);
	    }
	}
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
}
#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
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
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







-
+




-
-
-
+
+
+



+





-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
+
+
+

-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







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. */
    TkRegion 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;
    HIShapeRef srcRgn, dstRgn;
    HIMutableShapeRef dmgRgn = HIShapeCreateMutable();
    NSRect bounds, viewSrcRect, srcRect, dstRect;
    int result = 0;

    if (view) {

  	/*
	 * Get the scroll area in NSView coordinates (origin at bottom left).
	 */

  	bounds = [view bounds];
 	scrollSrc = NSMakeRect(macDraw->xOff + x,
 	viewSrcRect = 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.
	     */
	/*
	 * Scroll the rectangle.
	 */

 	    [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)];
  	}
    } else {
	dmgRgn = HIShapeCreateEmpty();
	TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
    }

    if (dmgRgn) {
	CFRelease(dmgRgn);
    }
	[view scrollRect:viewSrcRect by:NSMakeSize(dx, -dy)];

	/*
	 * Compute the damage region, using Tk coordinates (origin at top left).
	 */

	srcRect = CGRectMake(x, y, width, height);
	dstRect = CGRectOffset(srcRect, dx, dy);
	srcRgn = HIShapeCreateWithRect(&srcRect);
	dstRgn = HIShapeCreateWithRect(&dstRect);
	ChkErr(HIShapeDifference, srcRgn, dstRgn, dmgRgn);
	CFRelease(dstRgn);
	CFRelease(srcRgn);
	result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;

    }

    /*
     * Convert the HIShape dmgRgn into a TkRegion and store it.
     */

    TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);

    CFRelease(dmgRgn);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXSetUpGraphicsPort --
1238
1239
1240
1241
1242
1243
1244






1245
1246
1247
1248
1249
1250
1251
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252







+
+
+
+
+
+







    GC gc,
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = (MacDrawable *)d;
    Bool canDraw = true;
    TKContentView *view = nil;
    TkMacOSXDrawingContext dc = {};
    CGFloat drawingHeight;

#ifdef TK_MAC_DEBUG_CG
    fprintf(stderr, "TkMacOSXSetupDrawingContext: %s\n",
	    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
#endif

    /*
     * If the drawable is not a pixmap, get the associated NSView.
     */

    if (!(macDraw->flags & TK_IS_PIXMAP)) {
	view = (TKContentView *)TkMacOSXGetNSViewForDrawable(d);
1269
1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1270
1271
1272
1273
1274
1275
1276

1277


1278

1279
1280

1281
1282
1283
1284
1285
1286
1287







-
+
-
-

-


-








    /*
     * 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) {
    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);
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
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







-
+









+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+










-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+



















+
-
+
-







	 * 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);
	currentBounds = NSRectFromCGRect(CGContextGetClipBoundingBox(dc.context));
	if (!NSContainsRect(currentBounds, drawingBounds)) {
	    [view addTkDirtyRect:drawingBounds];
	}
    }

    /*
     * Finish configuring the drawing context.
     */

#ifdef TK_MAC_DEBUG_CG
    fprintf(stderr, "TkMacOSXSetupDrawingContext: pushing GState for %s\n",
	    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
#endif

    CGContextSaveGState(dc.context);
    CGContextSetTextDrawingMode(dc.context, kCGTextFill);
    { /* Restricted scope for t needed for C++ */
	drawingHeight = view ? [view bounds].size.height :
	    CGContextGetClipBoundingBox(dc.context).size.height;
    CGAffineTransform t = {
	.a = 1, .b = 0,
	.c = 0, .d = -1,
	.tx = 0,
	.ty = dc.portBounds.size.height
    };
	CGAffineTransform t = {
	    .a = 1, .b = 0,
	    .c = 0, .d = -1,
	    .tx = 0,
	    .ty = drawingHeight
	};

    dc.portBounds.origin.x += macDraw->xOff;
    dc.portBounds.origin.y += macDraw->yOff;
    CGContextSaveGState(dc.context);
    CGContextSetTextDrawingMode(dc.context, kCGTextFill);
    CGContextConcatCTM(dc.context, t);
	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)) {
	if (!HIShapeIsRectangular(dc.clipRgn)) {

	    /*
	     * We expect the clipping path dc.clipRgn to consist of the
	     * bounding rectangle of the drawable window, together with
	     * disjoint smaller rectangles inside of it which bound its
	     * geometric children.  In that case the even-odd rule will
	     * clip to the region inside the large rectangle and outside
	     * of the smaller rectangles.
	     */

	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);

#ifdef TK_MAC_DEBUG_CG
	    fprintf(stderr, "Setting complex clip for %s to:\n",
		    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
	    TkMacOSXPrintRectsInRegion(dc.clipRgn);
#endif

	    CGContextEOClip(dc.context);
	} else {
	    CGRect r;
	    HIShapeGetBounds(dc.clipRgn, &r);

#ifdef TK_MAC_DEBUG_CG
	    fprintf(stderr, "Current clip BBox is %s\n",
		    NSStringFromRect(CGContextGetClipBoundingBox(GET_CGCONTEXT)).UTF8String);
	    fprintf(stderr, "Setting clip for %s to rect %s:\n",
		    macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None",
		    NSStringFromRect(r).UTF8String);
#endif

	    CGContextClipToRect(dc.context, r);
	}
    }
    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) {
	    CGSize size = NSSizeToCGSize([view bounds].size);
	    CGContextSetPatternPhase(dc.context, CGSizeMake(
	    CGContextSetPatternPhase(dc.context, size);
	        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) {

1417
1418
1419
1420
1421
1422
1423
1424

1425
1426
1427
1428
1429


1430
1431
1432
1433
1434
1435
1436
1437
1446
1447
1448
1449
1450
1451
1452

1453





1454
1455

1456
1457
1458
1459
1460
1461
1462







-
+
-
-
-
-
-
+
+
-







	    CGContextSetLineJoin(dc.context, cgJoin[(unsigned) gc->join_style]);
	}
    }

end:

#ifdef TK_MAC_DEBUG_DRAWING
    if (!canDraw && win != NULL) {
    if (!canDraw && macDraw->winPtr != NULL) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);

	if (winPtr) {
	    fprintf(stderr, "Cannot draw in %s - postponing.\n",
		    Tk_PathName(winPtr));
	fprintf(stderr, "Cannot draw in %s - postponing.\n",
		Tk_PathName(macDraw->winPtr));
	}
    }
#endif

    if (!canDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
1458
1459
1460
1461
1462
1463
1464





1465
1466
1467

1468

1469
1470
1471


1472
1473
1474
1475
1476
1477
1478
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







+
+
+
+
+



+

+


-
+
+







void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);
	CGContextRestoreGState(dcPtr->context);

#ifdef TK_MAC_DEBUG_CG
	fprintf(stderr, "TkMacOSXRestoreDrawingContext: popped GState\n");
#endif

    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
	dcPtr->clipRgn = NULL;
    }

#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */
#endif

}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetClipRgn --
 *
1515
1516
1517
1518
1519
1520
1521























1522
1523
1524
1525
1526
1527
1528
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








    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 --
 *
1589
1590
1591
1592
1593
1594
1595
1596

1597
1598
1599
1600
1601
1602
1603
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1659







-
+







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;
	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;

	XOffsetRegion(gcClip, xOffset, yOffset);
	gcClipRgn = TkMacOSXGetNativeRegion(gcClip);
	if (clipRgn) {
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
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







-
+














-
+

-

















-
-
-
+
+
+
+
+










	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --
 * 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
TkpDrawFrameEx(
TkpDrawFrame(
    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);
    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.
1
2
3
4
5
6
7
8
9
10
11
12



13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9



10
11
12
13
14
15
16
17
18
19









-
-
-
+
+
+







/*
 * tkMacOSXEmbed.c --
 *
 *	This file contains platform-specific procedures for theMac to provide
 *	basic operations needed for application embedding (where one
 *	application can use as its main window an internal window from some
 *	other application). Currently only Toplevel embedding within the same
 *	Tk application is allowed on the Macintosh.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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"
39
40
41
42
43
44
45





46
47
48
49
50
51
52
53
54
55
56
57
58
59




































60
61
62
63
64
65
66
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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 = 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
117
118
119
120
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;
    (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));
	macWin = ckalloc(sizeof(MacDrawable));
	if (macWin == NULL) {
	    winPtr->privatePtr = NULL;
	    return None;
	}
	macWin->winPtr = winPtr;
	winPtr->privatePtr = macWin;
	macWin->visRgn = NULL;
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316







-
+







	}
    }

    /*
     * Make the embedded window.
     */

    macWin = (MacDrawable *)ckalloc(sizeof(MacDrawable));
    macWin = ckalloc(sizeof(MacDrawable));
    if (macWin == NULL) {
	winPtr->privatePtr = NULL;
	return TCL_ERROR;
    }

    macWin->winPtr = winPtr;
    macWin->view = nil;
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402







-
+








    /*
     * 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 = 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;
431
432
433
434
435
436
437




438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492



493
494
495
496
497
498
499







+
+
+
+











-
-
-







 */

MacDrawable *
TkMacOSXGetHostToplevel(
    TkWindow *winPtr)		/* Tk's structure for a window. */
{
    TkWindow *contWinPtr, *topWinPtr;

    if (!(winPtr && winPtr->privatePtr)) {
	return NULL;
    }

    topWinPtr = winPtr->privatePtr->toplevel->winPtr;
    if (!Tk_IsEmbedded(topWinPtr)) {
	return winPtr->privatePtr->toplevel;
    }
    contWinPtr = TkpGetOtherWindow(topWinPtr);

    /*
     * TODO: Here we should handle out of process embedding.
     */

    if (!contWinPtr) {
	return NULL;
    }
    return TkMacOSXGetHostToplevel(contWinPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpClaimFocus --
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
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570
571
572

573
574
575
576
577
578
579







-
+









-







 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData dummy,	/* Main window for application. */
    ClientData clientData,	/* 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);
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
593
594
595
596
597
598
599


600
601
602
603
604
605
606
607







-
-
+







	/*
	 * Parent id
	 */

	if (containerPtr->parent == None) {
	    Tcl_DStringAppendElement(&dString, "");
	} else if (all) {
	    sprintf(buffer, "0x%" TCL_Z_MODIFIER "x",
		    (size_t) containerPtr->parent);
	    snprintf(buffer, sizeof(buffer), "0x%lx", containerPtr->parent);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}

	/*
	 * Parent pathName
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
663
664
665
666
667
668
669



670
671
672
673
674
675
676







-
-
-







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 --
661
662
663
664
665
666
667
668

669
670
671
672
673
674
675
697
698
699
700
701
702
703

704
705
706
707
708
709
710
711







-
+







    Container *containerPtr;

    /*
     * TkpGetOtherWindow returns NULL if both windows are not in the same
     * process...
     */

    if (!(winPtr->flags & TK_BOTH_HALVES)) {
    if (!(winPtr && (winPtr->flags & TK_BOTH_HALVES))) {
	return NULL;
    }

    for (containerPtr = firstContainerPtr; containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parentPtr;
700
701
702
703
704
705
706
707

708
709
710
711
712
713
714
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750







-
+







 */

static void
EmbeddedEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = clientData;
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	EmbedWindowDeleted(winPtr);
    }
}

/*
735
736
737
738
739
740
741
742

743
744
745
746
747
748
749
771
772
773
774
775
776
777

778
779
780
781
782
783
784
785







-
+







 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = clientData;
    TkWindow *winPtr = (TkWindow *)clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;

    if (!firstContainerPtr) {
	/*
	 * When the interpreter is being dismantled this can be nil.
	 */
843
844
845
846
847
848
849
850

851
852
853
854
855
856
857
858
859

860
861
862
863
864
865
866
879
880
881
882
883
884
885

886
887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
902







-
+








-
+







 */

static void
EmbedStructureProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;
    Container *containerPtr = (Container *)clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {

	/*
         * Send a ConfigureNotify  to the embedded application.
         */

        if (containerPtr->embeddedPtr != None) {
        if (containerPtr->embeddedPtr != NULL) {
            TkDoConfigureNotify(containerPtr->embeddedPtr);
        }
	if (containerPtr->embedded != None) {
	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
	     */
897
898
899
900
901
902
903
904

905
906
907
908
909
910
911
933
934
935
936
937
938
939

940
941
942
943
944
945
946
947







-
+







 */

static void
EmbedActivateProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;
    Container *containerPtr = (Container *)clientData;

    if (containerPtr->embeddedPtr != NULL) {
	if (eventPtr->type == ActivateNotify) {
	    TkGenerateActivateEvents(containerPtr->embeddedPtr,1);
	} else if (eventPtr->type == DeactivateNotify) {
	    TkGenerateActivateEvents(containerPtr->embeddedPtr,0);
	}
932
933
934
935
936
937
938
939

940
941
942
943
944
945
946
968
969
970
971
972
973
974

975
976
977
978
979
980
981
982







-
+







 */

static void
EmbedFocusProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = clientData;
    Container *containerPtr = (Container *)clientData;
    Display *display;
    XEvent event;

    if (containerPtr->embeddedPtr != NULL) {
	display = Tk_Display(containerPtr->parentPtr);
	event.xfocus.serial = LastKnownRequestProcessed(display);
	event.xfocus.send_event = false;
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091







-







 *----------------------------------------------------------------------
 */

static void
EmbedSendConfigure(
    Container *containerPtr)	/* Information about the embedding. */
{
    (void)containerPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * EmbedWindowDeleted --
 *
1078
1079
1080
1081
1082
1083
1084



1085
1086
1087
1088
1089
1090
1091
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129







+
+
+







     * Find the Container structure for this window. Delete the information
     * about the embedded application and free the container's record.
     */

    prevPtr = NULL;
    containerPtr = firstContainerPtr;
    while (1) {
	if (containerPtr == NULL) {
	    return;
	}
	if (containerPtr->embeddedPtr == winPtr) {
	    /*
	     * We also have to destroy our parent, to clean up the container.
	     * Fabricate an event to do this.
	     */

	    if (containerPtr->parentPtr != NULL &&
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
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







-






-







-
-










-
-
-
-
-










 *----------------------------------------------------------------------
 */

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:
 */
Changes to macosx/tkMacOSXEntry.c.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * tkMacOSXEntry.c --
 *
 *	This file implements the native aqua entry widget.
 *
 * Copyright 2001, Apple Computer, Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 * Copyright © 2001 Apple Computer, Inc.
 * Copyright © 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 "tkEntry.h"
255
256
257
258
259
260
261
262

263
264
265


266
267
268
269
270
271
272
255
256
257
258
259
260
261

262
263


264
265
266
267
268
269
270
271
272







-
+

-
-
+
+







    /*
     * 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].x = (short)(Tk_Width(tkwin) - incDecWidth - 1);
    rects[0].y = 0;
    rects[0].width = incDecWidth + 1;
    rects[0].height = Tk_Height(tkwin);
    rects[0].width = (unsigned short)(incDecWidth + 1);
    rects[0].height = (unsigned short)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);
Changes to macosx/tkMacOSXEvent.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
1
2
3
4
5



6
7
8
9
10
11
12
13
14

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

30
31
32
33
34
35
36
37





-
-
-
+
+
+






-
+














-
+







/*
 * tkMacOSXEvent.c --
 *
 *	This file contains the basic Mac OS X Event handling routines.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 "tkMacOSXEvent.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);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), theEvent);
#endif
    NSEvent	    *processedEvent = theEvent;
    NSEventType	    type = [theEvent type];
    NSInteger	    subtype;

    switch ((NSInteger)type) {
    case NSAppKitDefined:
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
101
102
103
104
105
106
107





108
















109
110
111
112
113
114
115
116







-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








    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:
 */
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
24
25
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * tkMacOSXEvent.h --
 *
 *	Declarations of Macintosh specific functions for implementing the
 *	Mac OS X Notifier.
 *
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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

/*
 * Currently nothing needs to be declared here.
 */

#endif
Added macosx/tkMacOSXFileTypes.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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
There are situations where a graphical user interface needs to know the file
type (i.e. data format) of a file.  The two main ones are when generating an
icon to represent a file, and when filtering the choice of files in a file
open or save dialog.

Early Macintosh systems used OSTypes as identifiers for file types.  An OSType
is a FourCC datatype - four bytes which can be packed into a 32 bit integer.  In
the HFS filesystem they were included in the file metadata.  The metadata also
included another OSType (the Creator Code) which identified the application
which created the file.

In OSX 10.4 the Uniform Type Identifier was introduced as an alternative way to
describe file types.  These are strings (NSStrings, actually) in a reverse DNS
format, such as "com.apple.application-bundle".  Apple provided a tool for
converting OSType codes to Uniform Type Identifiers, which they deprecated in
macOS 12.0 after introducing the UTType class in macOS 11.0.  An instance of the
UTType class has properties which give the Uniform Type Identifier as well as
the preferred file name extension for a given file type.

This module provides tools for working with file types which are meant to abstract
the many variants that Apple has used over the years, and which can be used
without generating deprecation warnings.
*/

#include "tkMacOSXPrivate.h"

#define CHARS_TO_OSTYPE(string) (OSType) string[0] << 24 | \
                                (OSType) string[1] << 16 | \
                                (OSType) string[2] <<  8 | \
                                (OSType) string[3]

MODULE_SCOPE NSString *TkMacOSXOSTypeToUTI(OSType ostype) {
    char string[5];
    string[4] = '\0';
    string[3] = ostype;
    string[2] = ostype >> 8;
    string[1] = ostype >> 16;
    string[0] = ostype >> 24;
    NSString *tag = [NSString stringWithCString:string encoding:NSMacOSRomanStringEncoding];
    if (tag == nil) {
	return nil;
    }
    NSString *result = nil;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
    if (@available(macOS 11.0, *)) {
	return [UTType typeWithTag:tag tagClass:@"com.apple.ostype" conformingToType:nil].identifier;
    }
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
    result = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, (CFStringRef)tag, NULL);
#endif
    return result;
}

/*
 * The NSWorkspace method iconForFileType, which was deprecated in macOS 12.0, would
 * accept an NSString which could be an encoding of an OSType, or a file extension,
 * or a Uniform Type Idenfier.  This function can serve as a replacement.
 */
MODULE_SCOPE NSImage *TkMacOSXIconForFileType(NSString *filetype) {
#if MAC_OS_X_VERSION_MAX_ALLOWED < 110000
// We don't have UTType but iconForFileType is not deprecated, so use it.
    return [[NSWorkspace sharedWorkspace] iconForFileType:filetype];
#else
// We might have UTType but iconForFileType might be deprecated.
    if (@available(macOS 11.0, *)) {
	/* Yes, we do have UTType */
	if (filetype == nil) {
	    /*
	     * Bug 9be830f61b: match the behavior of
	     * [NSWorkspace.sharedWorkspace iconForFileType:nil]
	     */
	     filetype = @"public.data";
	}
	UTType *uttype = [UTType typeWithIdentifier: filetype];
	if (uttype == nil || !uttype.isDeclared) {
	    uttype = [UTType typeWithFilenameExtension: filetype];
	}
	if (uttype == nil || (!uttype.isDeclared && filetype.length == 4)) {
	    OSType ostype = CHARS_TO_OSTYPE(filetype.UTF8String);
	    NSString *UTI = TkMacOSXOSTypeToUTI(ostype);
	    if (UTI) {
		uttype = [UTType typeWithIdentifier:UTI];
	    }
	}
	if (uttype == nil || !uttype.isDeclared) {
	    return nil;
	}
	return [[NSWorkspace sharedWorkspace] iconForContentType:uttype];
    } else {
	/* No, we don't have UTType. */
 #if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
	/* but iconForFileType is not deprecated, so we can use it. */
    return [[NSWorkspace sharedWorkspace] iconForFileType:filetype];
 #else
    /*
     * Cannot be reached: MIN_REQUIRED >= 110000 yet 11.0 is not available.
     * But the compiler can't figure that out, so it will warn about an
     * execution path with no return value unless we put a return here.
     */
    return nil;
 #endif
    }
#endif
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
Changes to macosx/tkMacOSXFont.c.
1
2
3
4
5
6
7
8
9



10
11
12
13
14
15
16
1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16






-
-
-
+
+
+







/*
 * 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.
 * Copyright © 2002-2004 Benjamin Riefenstahl, Benjamin.Riefenstahl@epost.de
 * Copyright © 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"
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57







-
+







 */

#define SYSTEMFONT_NAME		"system"
#define APPLFONT_NAME		"application"
#define MENUITEMFONT_NAME	"menu"

struct SystemFontMapEntry {
    const ThemeFontID id;
    ThemeFontID id;
    const char *systemName;
    const char *tkName;
    const char *tkName1;
};

#define ThemeFont(n, ...) { kTheme##n##Font, "system" #n "Font", ##__VA_ARGS__ }
static const struct SystemFontMapEntry systemFontMap[] = {
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84







-
+







    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 }
    { (ThemeFontID)-1, NULL, NULL, NULL }
};
#undef ThemeFont

static int antialiasedTextEnabled = -1;
static NSCharacterSet *whitespaceCharacterSet = nil;
static NSCharacterSet *lineendingCharacterSet = nil;

108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+














-
+








- (instancetype)initWithTclUtfBytes:(const void *)bytes
		       length:(NSUInteger)len
{
    self = [self init];
    if (self) {
	Tcl_DStringInit(&_ds);
	Tcl_UtfToChar16DString(bytes, len, &_ds);
	Tcl_UtfToUniCharDString((const char *)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;
	_UTF8String = _string.UTF8String;
    }
    return self;
}

- (void)dealloc
{
    Tcl_DStringFree(&_ds);
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
145
146
147
148
149
150
151




152
153
154
155
156
157
158







-
-
-
-







}

- (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.
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
167
168
169
170
171
172
173

174

175
176
177
178
179
180
181
182







-

-
+







	    p += Tcl_UniCharToUtf([_string characterAtIndex: index], p);
	}
	Tcl_DStringSetLength(&_ds, p - Tcl_DStringValue(&_ds));
    }
    return _ds;
}

#ifndef __clang__
@synthesize UTF8String = _UTF8String;
#endif
@synthesize DString = _ds;
@end

#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
	((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
	((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)

/*
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252







-
+







{
    NSFontManager *fm = [NSFontManager sharedFontManager];
    NSFont *nsFont, *dflt = nil;
    #define defaultFont (dflt ? dflt : (dflt = [NSFont systemFontOfSize:0]))
    NSString *family;

    if (familyName) {
	family = [[[NSString alloc] initWithUTF8String:familyName] autorelease];
	family = [[[TKNSString alloc] initWithTclUtfBytes:familyName length:-1] autorelease];
    } else {
	family = [defaultFont familyName];
    }
    if (size == 0.0) {
	size = [defaultFont pointSize];
    }
    nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];
348
349
350
351
352
353
354
355
356
357



358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376


377
378
379
380
381
382
383
343
344
345
346
347
348
349



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369


370
371
372
373
374
375
376
377
378







-
-
-
+
+
+

















-
-
+
+







	renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ?
		NSFontIntegerAdvancementsRenderingMode :
		NSFontAntialiasedRenderingMode;
    }
    nsFont = [nsFont screenFontWithRenderingMode:renderingMode];
    GetTkFontAttributesForNSFont(nsFont, faPtr);
    fmPtr = &fontPtr->font.fm;
    fmPtr->ascent = floor([nsFont ascender] + [nsFont leading] + 0.5);
    fmPtr->descent = floor(-[nsFont descender] + 0.5);
    fmPtr->maxWidth = [nsFont maximumAdvancement].width;
    fmPtr->ascent = (int)floor([nsFont ascender] + [nsFont leading] + 0.5);
    fmPtr->descent = (int)floor(-[nsFont descender] + 0.5);
    fmPtr->maxWidth = (int)[nsFont maximumAdvancement].width;
    fmPtr->fixed = [nsFont isFixedPitch];   /* Does not work for all fonts */

    /*
     * The ascent, descent and fixed fields are not correct for all fonts, as
     * a workaround deduce that info from the metrics of some typical glyphs,
     * along with screenfont kerning (space advance difference to printer font)
     */

    bounds = [nsFont boundingRectForFont];
    if (CTFontGetGlyphsForCharacters((CTFontRef) nsFont, ch, glyphs, nCh)) {
	fmPtr->fixed = [nsFont advancementForGlyph:glyphs[0]].width ==
		[nsFont advancementForGlyph:glyphs[1]].width;
	bounds = NSRectFromCGRect(CTFontGetBoundingRectsForGlyphs((CTFontRef)
		nsFont, defaultOrientation, ch, boundingRects, nCh));
	kern = [nsFont advancementForGlyph:glyphs[2]].width -
		[fontPtr->nsFont advancementForGlyph:glyphs[2]].width;
    }
    descent = floor(-bounds.origin.y + 0.5);
    ascent = floor(bounds.size.height + bounds.origin.y + 0.5);
    descent = (int)floor(-bounds.origin.y + 0.5);
    ascent = (int)floor(bounds.size.height + bounds.origin.y + 0.5);
    if (ascent > fmPtr->ascent) {
	fmPtr->ascent = ascent;
    }
    if (descent > fmPtr->descent) {
	fmPtr->descent = descent;
    }
    nsAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
608
609
610
611
612
613
614

615
616
617
618
619
620
621
622







-
+







				 * 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);
    CGFloat points = floor(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);
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
630
631
632
633
634
635
636

637
638
639
640
641
642
643
644







-
+







    }
    if (!nsFont) {
	Tcl_Panic("Could not determine NSFont from TkFontAttributes");
    }
    if (tkFontPtr == NULL) {
	fontPtr = (MacFont *)ckalloc(sizeof(MacFont));
    } else {
	fontPtr = (MacFont *) tkFontPtr;
	fontPtr = (MacFont *)tkFontPtr;
	TkpDeleteFont(tkFontPtr);
    }
    CFRetain(nsFont); /* Always needed to allow unconditional CFRelease below */
    InitFont(nsFont, faPtr, fontPtr);

    return (TkFont *) fontPtr;
}
770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
765
766
767
768
769
770
771

772
773
774
775
776
777
778
779







-
+







 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    TCL_UNUSED(Tk_Window),		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    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;
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
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







-
-
-
+
+
+












-
-
-
+
+
+








-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+





-
-
-
+
+
+
















-
+


















-
+







	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.
         */
	/*
	 * 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.
         */
	/*
	 * 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 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) && (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.
         */
	/*
	 * 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);
	}

    }
    CFRelease(typesetter);
    [attributedString release];
    [string release];
    length = ceil(width - offset);
    fit = (Tcl_UtfAtIndex(source, index) - source) - rangeStart;
    fit = (TkUtfAtIndex(source, index) - source) - rangeStart;
done:
#ifdef TK_MAC_DEBUG_FONTS
    TkMacOSXDbgMsg("measure: source=\"%s\" range=\"%.*s\" maxLength=%d "
	    "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 " : "",
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160







-







    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. */
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
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







-
+




-
-
-
+
+
+








-
+

+
-
-
+
+
+





+




-
+




-
-
-
+
+
+







    NSAttributedString *attributedString;
    CTTypesetterRef typesetter;
    CFIndex start, length;
    CTLineRef line, full=nil;
    MacDrawable *macWin = (MacDrawable *)drawable;
    TkMacOSXDrawingContext drawingContext;
    CGContextRef context;
    CGColorRef fg;
    CGColorRef fg = NULL;
    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)) {
    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);
    TkSetMacColor(gc->foreground, &fg);
    attributes = [fontPtr->nsAttributes mutableCopy];
    if (fg) {
    [attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
    CFRelease(fg);
	[attributes setObject:(id)fg forKey:(id)kCTForegroundColorAttributeName];
	CGColorRelease(fg);
    }
    nsFont = [attributes objectForKey:NSFontAttributeName];
    [nsFont setInContext:GET_NSCONTEXT(context, NO)];
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    attributedString = [[NSAttributedString alloc] initWithString:string
	    attributes:attributes];
    [string release];
    typesetter = CTTypesetterCreateWithAttributedString(
	    (CFAttributedStringRef)attributedString);
    textX += (CGFloat) macWin->xOff;
    textY += (CGFloat) macWin->yOff;
    height = drawingContext.portBounds.size.height;
    height = [drawingContext.view bounds].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);
	     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) {

1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260







-







	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);
}

#pragma mark -
#pragma mark Accessors:

1321
1322
1323
1324
1325
1326
1327

1328
1329
1330
1331
1332
1333
1334
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331







+







 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

#undef TkMacOSXIsCharacterMissing
int
TkMacOSXIsCharacterMissing(
    TCL_UNUSED(Tk_Font),		/* The font we are looking in. */
    TCL_UNUSED(unsigned int))	/* The character we are looking for. */
{
    return 0;
}
1363
1364
1365
1366
1367
1368
1369
1370

1371
1372
1373
1374
1375
1376
1377
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1374







-
+







		traitsOfFont:nsFont];
	id underline = [nsAttributes objectForKey:
		NSUnderlineStyleAttributeName];
	id strikethrough = [nsAttributes objectForKey:
		NSStrikethroughStyleAttributeName];

	objv[i++] = Tcl_NewStringObj(familyName, -1);
	objv[i++] = Tcl_NewWideIntObj([nsFont pointSize]);
	objv[i++] = Tcl_NewWideIntObj((Tcl_WideInt)floor([nsFont pointSize] + 0.5));
#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);
Changes to macosx/tkMacOSXFont.h.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17






-
-
-
-
+
+
+
+







/*
 * 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>
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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
Changes to macosx/tkMacOSXHLEvents.c.
1
2
3
4
5
6
7
8
9
10





11
12
13
14
15
16
17
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.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2015-2019 Marc Culler
 * Copyright © 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>
67
68
69
70
71
72
73

74
75
76
77
78
79
80
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81







+







{
    (void)sender;
    [self handleQuitApplicationEvent:Nil withReplyEvent:Nil];
}

- (void) superTerminate: (id) sender
{
    (void) sender;
    [super terminate:nil];
}

- (void) preferences: (id) sender
{
    (void)sender;
    [self handleShowPreferencesEvent:Nil withReplyEvent:Nil];
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
232
233
234
235
236
237
238

239
240
241
242
243
244
245







-







    }

    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);
    }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
257
258
259
260
261
262
263

264
265
266
267
268
269
270







-








    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
{
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299

300
301
302
303
304
305
306
284
285
286
287
288
289
290

291
292
293
294
295
296
297

298
299
300
301
302
303
304
305







-
+






-
+







    if (theDesc == nil) {
	return;
    }

    err = AEGetParamPtr(theDesc, keyDirectObject, typeWildCard, &initialType,
			NULL, 0, NULL);
    if (err != noErr) {
	sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)err);
	snprintf(errString, sizeof(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");
    	snprintf(errString, sizeof(errString), "AEDoScriptHandler: extra parameters");
    	AEPutParamPtr((AppleEvent*)[replyEvent aeDesc], keyErrorString,
		      typeChar,errString, strlen(errString));
    	return;
    }

    if (initialType == typeFileURL || initialType == typeAlias) {

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
319
320
321
322
323
324
325

326
327
328
329
330
331
332







-







                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)) {
        /*
349
350
351
352
353
354
355
356

357
358
359
360

361
362
363
364
365
366
367
347
348
349
350
351
352
353

354
355
356


357
358
359
360
361
362
363
364







-
+


-
-
+







		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);
                    ProcessAppleEvent((ClientData)AEInfo);
                } else {
                    AEInfo->replyEvent = nil;
                    Tcl_DoWhenIdle(ProcessAppleEvent, AEInfo);
                    ProcessAppleEvent(AEInfo);
                    ProcessAppleEvent((ClientData)AEInfo);
                }
	    }
	}
    }
}

- (void)handleURLEvent:(NSAppleEventDescriptor*)event
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
373
374
375
376
377
378
379

380
381
382
383
384
385
386







-








    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 -
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
653
633
634
635
636
637
638
639

640
641
642
643
644
645
646
647
648
649







-
+









   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:
 */
Changes to 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
1
2
3
4
5




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93





-
-
-
-
+
+
+
+






+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/*
 * 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.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2017-2021 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 "tkMacOSXConstants.h"
#include "xbytes.h"

static CGImageRef CreateCGImageFromPixmap(Drawable pixmap);
static CGImageRef CreateCGImageFromDrawableRect( Drawable drawable,
	   int x, int y, unsigned int width, unsigned int height);

/* Pixel formats
 *
 * Tk uses the XImage structure defined in Xlib.h for storing images.  The
 * image data in an XImage is a 32-bit aligned array of bytes.  Interpretation
 * of that data is not specified, but the structure includes parameters which
 * provide interpretation hints so that an application can use a family of
 * different data structures.
 *
 * The possible values for the XImage format field are XYBitmap, XYPixmap and
 * ZPixmap.  The macOS port does not support the XYPixmap format.  This means
 * that bitmap images are stored as a single bit plane (XYBitmap) and that
 * color images are stored as a sequence of pixel values (ZPixmap).
 *
 * For a ZPixmap, the number of bits allocated to each pixel is specified by
 * the bits_per_pixel field of the XImage structure.  The functions in this
 * module which convert between XImage and native CGImage or NSImage structures
 * only support XImages with 32 bits per pixel.  The ImageGetPixel and PutPixel
 * implementations in this file allow 1, 4, 8, 16 or 32 bits per pixel, however.
 *
 * In tkImgPhInstance.c the layout used for pixels is determined by the values
 * of the red_mask, blue_mask and green_mask fields in the XImage structure.
 * The Aqua port always sets red_mask = 0xFF0000, green_mask = 0xFF00, and
 * blue_mask = 0xFF. This means that a 32bpp ZPixmap XImage uses ARGB32 pixels,
 * with small-endian byte order BGRA. The data array for such an XImage can be
 * passed directly to construct a CGBitmapImageRep if one specifies the
 * bitmapInfo as kCGBitmapByteOrder32Big | kCGImageAlphaLast.
 *
 * The structures below describe the bitfields in two common 32 bpp pixel
 * layouts.  Note that bit field layouts are compiler dependent. The layouts
 * shown in the comments are those produced by clang and gcc.  Also note
 * that kCGBitmapByteOrder32Big is consistently set when creating CGImages or
 * CGImageBitmapReps.
 */

/* RGBA32 0xRRGGBBAA (Byte order is RGBA on big-endian systems.)
 * This is used by NSBitmapImageRep when the bitmapFormat property is 0,
 * the default value.
 */

typedef struct RGBA32pixel_t {
    unsigned red: 8;
    unsigned green: 8;
    unsigned blue: 8;
    unsigned alpha: 8;
} RGBA32pixel;

/*
 * ARGB32 0xAARRGGBB (Byte order is ARGB on big-endian systems.)
 * This is used by Aqua Tk for XImages and by NSBitmapImageReps whose
 * bitmapFormat property is NSAlphaFirstBitmapFormat.
 */

typedef struct ARGB32pixel_t {
    unsigned blue: 8;
    unsigned green: 8;
    unsigned red: 8;
    unsigned alpha: 8;
} ARGB32pixel;

typedef union pixel32_t {
    unsigned int uint;
    RGBA32pixel rgba;
    ARGB32pixel argb;
} pixel32;

#pragma mark XImage handling

int
_XInitImageFuncPtrs(
    TCL_UNUSED(XImage *)) /* image */
{
44
45
46
47
48
49
50
51

52
53
54
55
56

57
58


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


80
81
82
83




84
85
86
87
88
89
90






91
92
93


94

95
96
97
98

99
100

101
102
103
104
105

106
107
108
109
110
111
112
113

114
115
116
117
118
119

120

121
122


123

124
125
126
127
128

129
130
131
132
133
134
135
110
111
112
113
114
115
116

117
118
119
120
121

122
123

124
125
126
127
128
129
130

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147




148
149
150
151
152






153
154
155
156
157
158

159
160
161
162

163

164
165
166
167
168
169
170
171
172
173
174

175
176

177
178
179
180
181
182
183
184
185




186
187
188
189
190
191
192

193

194
195
196

197
198
199
200
201
202
203
204







-
+




-
+

-
+
+





-















+
+
-
-
-
-
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+
-


+
+
-
+
-



+


+




-
+

-






+


-
-
-
-
+

+


+
+
-
+
-



-
+







 *
 *----------------------------------------------------------------------
 */

static void ReleaseData(
    void *info,
    TCL_UNUSED(const void *), /* data */
    TCL_UNUSED(size_t))       /* size */
    TCL_UNUSED(size_t))        /* size */
{
    ckfree(info);
}

CGImageRef
static CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image)
    XImage *image,
    uint32_t bitmapInfo)
{
    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;
	data = (char *)ckalloc(len);
	if (data) {
	if (image->bitmap_bit_order != MSBFirst) {
	    char *srcPtr = image->data + image->xoffset;
	    char *endPtr = srcPtr + len;
	    char *destPtr = (data = (char *)ckalloc(len));
	    if (image->bitmap_bit_order != MSBFirst) {
		char *srcPtr = image->data + image->xoffset;
		char *endPtr = srcPtr + len;
		char *destPtr = data;

	    while (srcPtr < endPtr) {
		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
	    }
	} else {
	    data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	}
		while (srcPtr < endPtr) {
		    *destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
		}
	    } else {
		memcpy(data, image->data + image->xoffset, len);
	    }
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);
	    if (!provider) {
		ckfree(data);
	}
	    }
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height,
		    bitsPerComponent, bitsPerPixel, image->bytes_per_line,
		    provider, decode, 0);
	    CGDataProviderRelease(provider);
	}
    } else if ((image->format == ZPixmap) && (image->bits_per_pixel == 32)) {

	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
	if (image->width == 0 && image->height == 0) {

	if (image->width == 0 && image->height == 0) {
	    /*
	     * CGCreateImage complains on early macOS releases.
	     */

	    return NULL;
	}
	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);
	bitmapInfo |= kCGImageAlphaLast;
	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	data = (char *)ckalloc(len);
	if (data) {
	    memcpy(data, image->data + image->xoffset, len);
	    provider = CGDataProviderCreateWithData(data, data, len,
		    releaseData);
	    if (!provider) {
		ckfree(data);
	}
	    }
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
		    provider, decode, 0, kCGRenderingIntentDefault);
	    CFRelease(provider);
	    CGDataProviderRelease(provider);
	}
	if (colorspace) {
	    CFRelease(colorspace);
	}
    } else {
	TkMacOSXDbgMsg("Unsupported image type");
    }
201
202
203
204
205
206
207

208

209
210
211
212
213
214



215

216
217
218
219
220
221
222
270
271
272
273
274
275
276
277

278






279
280
281

282
283
284
285
286
287
288
289







+
-
+
-
-
-
-
-
-
+
+
+
-
+







    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;
		ARGB32pixel *pixel = (ARGB32pixel *)srcPtr;
	    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];
		r = pixel->red;
		g = pixel->green;
		b = pixel->blue;
	    }*/
	    }
	    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 */
245
246
247
248
249
250
251
252




253
254
255
256
257
258
259
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326
327
328
329







-
+
+
+
+







}

/*
 *----------------------------------------------------------------------
 *
 * ImagePutPixel --
 *
 *	Set a single pixel in an image.
 *	Set a single pixel in an image.  The pixel is provided as an unsigned
 *      32-bit integer.  The value of that integer is interpreted by assuming
 *      that its low-order N bits have the format specified by the XImage,
 *      where N is equal to the bits_per_pixel field of the XImage.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
271
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287

288
289
290
291
292
293
294


295
296
297
298

299
300
301
302
303
304
305
341
342
343
344
345
346
347



348
349

350

351
352

353

354
355




356
357
358
359
360

361
362
363
364
365
366
367
368







-
-
-


-
+
-


-
+
-


-
-
-
-
+
+



-
+







	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) |
		*((unsigned short*) dstPtr) = pixel & 0xffff;
			((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
		break;
	    case 8:
		*dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
		*dstPtr = pixel & 0xff;
			((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));
		*dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (pixel & 0x0f)) :
			((*dstPtr & 0x0f) | ((pixel << 4) & 0xf0));
		break;
		}
	    case 1:
		*dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
		*dstPtr = pixel ? (*dstPtr | (0x80 >> (x % 8))) :
			(*dstPtr & ~(0x80 >> (x % 8)));
		break;
	    }
	}
    }
    return 0;
}
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339


340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400


401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430







-
+











-
-
+
+




















-
+







 *
 *----------------------------------------------------------------------
 */

XImage *
XCreateImage(
    Display* display,
    TCL_UNUSED(Visual*),  /* visual */
    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));
    LastKnownRequestProcessed(display)++;
    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.
	 * Use 16 byte alignment for best Quartz performance.
	 */

	ximage->bitmap_pad = 128;
    }
    if (bytes_per_line) {
	ximage->bytes_per_line = bytes_per_line;
    } else {
388
389
390
391
392
393
394
395

396

397
398
399













400
401
402

403
404
405
406
407
408
409



410
411



412
413
414
415
416
417
418
419
420
421

422
423
424

425



426

427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

452
453
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
451
452
453
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







-
+

+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+


-
+







+
+
+
-
-
+
+
+









-
+



+

+
+
+
-
+





-
+









-









+



+


-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+
+
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
+
+




-
+
-
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
+
+








    return ximage;
}

/*
 *----------------------------------------------------------------------
 *
 * XPutImage --
 * TkPutImage, XPutImage, TkpPutRGBAImage --
 *
 *	These functions, which all have the same signature, copy a rectangular
 *	Copies a rectangular subimage of an XImage into a drawable.  Currently
 *      this is only called by TkImgPhotoDisplay, using a Window as the
 *      drawable.
 *      subimage of an XImage into a drawable.  The first two are identical on
 *      macOS.  They assume that the XImage data has the structure of a 32bpp
 *      ZPixmap in which the image data is an array of 32bit integers packed
 *      with 8 bit values for the Red Green and Blue channels.  They ignore the
 *      fourth byte.  The function TkpPutRGBAImage assumes that the XImage data
 *      has been extended by using the fourth byte to store an 8-bit Alpha
 *      value.  (The Alpha data is assumed not to pre-multiplied).  The image
 *      is then drawn into the drawable using standard Porter-Duff Source Atop
 *      Composition (kCGBlendModeSourceAtop in Apple's Core Graphics).
 *
 *      The TkpPutRGBAImage function is used by TkImgPhotoDisplay to render photo
 *      images if the compile-time variable TK_CAN_RENDER_RGBA is defined in
 *      a platform's tkXXXXPort.h header, as is the case for the macOS Aqua port.
 *
 * Results:
 *	None.
 *	These functions return either BadDrawable or Success.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
 *----------------------------------------------------------------------
 */

#define USE_ALPHA (kCGImageAlphaLast | kCGBitmapByteOrder32Big)
#define IGNORE_ALPHA (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little)

int
XPutImage(
static int
TkMacOSXPutImage(
    uint32_t pixelFormat,
    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. */
    unsigned int height)	/* destination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = (MacDrawable *)drawable;
    int result = Success;

    if (width <= 0 || height <= 0) {
	return Success; /* Is OK. Nothing to see here, literally. */
    }
    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect bounds, srcRect, dstRect;
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image, pixelFormat);

	/*
	 * 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");
	    result = BadDrawable;
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
	result = BadDrawable;
    }
    TkMacOSXRestoreDrawingContext(&dc);
    return Success;
    return result;
}

int XPutImage(
    Display* display,
    Drawable drawable,
    GC gc,
    XImage* image,
    int src_x,
    int src_y,
    int dest_x,
    int dest_y,
    unsigned int width,
    unsigned int height) {
    return TkMacOSXPutImage(IGNORE_ALPHA, display, drawable, gc, image,
			    src_x, src_y, dest_x, dest_y, width, height);
}

int TkPutImage(
    TCL_UNUSED(unsigned long *),
    TCL_UNUSED(int),
    Display* display,
    Drawable drawable,
    GC gc,
    XImage* image,
    int src_x,
    int src_y,
    int dest_x,
    int dest_y,
    unsigned int width,
    unsigned int height) {
    return TkMacOSXPutImage(IGNORE_ALPHA, display, drawable, gc, image,
		     src_x, src_y, dest_x, dest_y, width, height);
}

int TkpPutRGBAImage(
    Display* display,
    Drawable drawable,
    GC gc,
    XImage* image,
    int src_x,
    int src_y,
    int dest_x,
    int dest_y,
    unsigned int width,
    unsigned int height) {
    return TkMacOSXPutImage(USE_ALPHA, display, drawable, gc, image,
		     src_x, src_y, dest_x, dest_y, width, height);
}


/*
 *----------------------------------------------------------------------
 *
 * CreateCGImageFromDrawableRect
 *
 *	Extract image data from a MacOSX drawable as a CGImage.
 *	Extract image data from a MacOSX drawable as a CGImage.  The drawable
 *      may be either a pixmap or a window, but there issues in the case of
 *      a window.
 *
 *      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.
 *      CreateCGImageFromDrawableRect is called by XGetImage and XCopyArea.
 *      The Tk core uses these two functions on some platforms in order to
 *      implement explicit double-buffered drawing -- a pixmap is copied from a
 *      window, modified using CPU-based graphics composition, and then copied
 *      back to the window.  Platforms, such as macOS, on which the system
 *      provides double-buffered drawing and GPU-based composition operations
 *      can avoid calls to XGetImage and XCopyArea from the core by defining
 *      the compile-time variable TK_NO_DOUBLE_BUFFERING.  Nonetheless, these
 *      two functions are in the stubs table and therefore could be used by
 *      extensions.
 *
 *      This implementation does not work correctly.  Originally it relied on
 *      The implementation here does not always work correctly when the source
 *      is a window.  The original version of this function 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
 *      is being used here.  However, cacheDisplayInRect works by calling
 *      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
 *      [NSView drawRect] after setting the current graphics context to be one
 *      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
 *      which draws to a bitmap.  There are situations in which this can be
 *      used, e.g. when taking a screenshot of a window.  But it cannot be used
 *      as part of a normal display procedure, using the copy-modify-paste
 *      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
 *      paradigm that is the basis of the explicit double-buffering.  Since the
 *      copy operation will call the same display procedure that is calling
 *      this function via XGetImage or XCopyArea, this would create an infinite
 *      recursion.
 *      of rewriting of the drawRect method. Perhaps the next release of OSX
 *      will include some more helpful ways of doing this.
 *
 *      An alternative to the copy-modify-paste paradigm is to use GPU-based
 *      graphics composition, clipping to the specified rectangle.  That is
 *      the approach that must be followed by display procedures on macOS.
 *
 * 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
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
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







-
-

-
-
-
-
-
-

-
+
-
-
-
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
-
-
-
-
+
+
-
-
-
-
+
-
-
+
+
+
+
+







    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);
	CGContextRetain(cg_context);
	if (cg_image) {
	    result = CGImageCreateWithImageInRect(cg_image, image_rect);
	    CGImageRelease(cg_image);
	}
    } else if (TkMacOSXGetNSViewForDrawable(mac_drawable) != NULL) {

    } else {
	NSView *view = TkMacOSXGetNSViewForDrawable(mac_drawable);
	if (view == nil) {
	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	    TkMacOSXDbgMsg("Invalid source drawable");
	    return NULL;
	}
	NSSize size = view.frame.size;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
		view_height - height - y - mac_drawable->yOff,
		width, height);

	NSUInteger view_width = size.width, view_height = size.height;
        NSUInteger bytesPerPixel = 4,
	    bytesPerRow = bytesPerPixel * view_width,
	    bitsPerComponent = 8;
	/*
	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
	 * not have a valid CGContext, doing this will silently corrupt memory
	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
	cg_context = CGBitmapContextCreate(NULL, view_width, view_height,
			 bitsPerComponent, bytesPerRow, colorSpace,
			 kCGImageAlphaPremultipliedLast |
			 kCGBitmapByteOrder32Big);
	CFRelease(colorSpace);
	[view.layer renderInContext:cg_context];
	 * and make a big mess. So, in that case, we just return NULL.
	 */

	if (view == [NSView focusView]) {
    }
    if (cg_context) {
	    bitmapRep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmapRep];
	    result = [bitmapRep CGImage];
	    CFRelease(bitmapRep);
	cg_image = CGBitmapContextCreateImage(cg_context);
	CGContextRelease(cg_context);
	} else {
	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
	    result = NULL;
	}
    }
    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    if (cg_image) {
	CGRect rect = CGRectMake(x + mac_drawable->xOff, y + mac_drawable->yOff,
				 width, height);
	result = CGImageCreateWithImageInRect(cg_image, rect);
	CGImageRelease(cg_image);
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
-
-









-
+


-
+


-
+
-







 *	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 */
    TCL_UNUSED(unsigned long),  /* plane_mask */
    int format)
{
    NSBitmapImageRep* bitmapRep = NULL;
    NSBitmapImageRep* bitmapRep = nil;
    NSUInteger bitmap_fmt = 0;
    XImage* imagePtr = NULL;
    char* bitmap = 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;
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
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







-
-
-
-
-
-
-
+
+
+
+
+

-
+


+

-
+

+
+
+
+
+
-
+
-
-
-
+
+

-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-






+





+







	} 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) {
	if ((bitmap_fmt != 0 && bitmap_fmt != NSAlphaFirstBitmapFormat)
	    || [bitmapRep samplesPerPixel] != 4
	    || [bitmapRep isPlanar] != 0
	    || bytes_per_row < 4 * width
	    || size != bytes_per_row * height) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmapRep);
	    [bitmapRep release];
	    return NULL;
	}
	bitmap = (char *)ckalloc(size);
	memcpy(bitmap, (char *)[bitmapRep bitmapData], size);
	CFRelease(bitmapRep);
	[bitmapRep release];

	for (row = 0, n = 0; row < height; row++, n += bytes_per_row) {
	    for (m = n; m < n + 4*width; m += 4) {
		pixel32 pixel = *((pixel32 *)(bitmap + m));
		if (bitmap_fmt == 0) { // default format

	/*
		    /*
	 * When Apple extracts a bitmap from an NSView, it may be in either
	 * BGRA or ABGR format.  For an XImage we need RGBA.
	 */
		     * This pixel is in ARGB32 format.  We need RGBA32.
		     */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;

		    pixel32 flipped;
		    flipped.rgba.red = pixel.argb.red;
	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);

		    flipped.rgba.green = pixel.argb.green;
		    flipped.rgba.blue = pixel.argb.blue;
		    flipped.rgba.alpha = pixel.argb.alpha;
		    *((pixel32 *)(bitmap + m)) = flipped;
		} else { // bitmap_fmt = NSAlphaFirstBitmapFormat
		    *((pixel32 *)(bitmap + m)) = pixel;
		}
		*(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;
}

/*
 *----------------------------------------------------------------------
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
856
857
858
859
860
861
862

863
864
865
866
867
868
869
870







-
+







    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *)src;
    CGImageRef img = NULL;
    CGRect bounds, srcRect, dstRect;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (!width || !height) {
	return BadDrawable;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, &dc)) {
	TkMacOSXDbgMsg("Failed to setup drawing context.");
	return BadDrawable;
807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
930
931
932
933
934
935
936

937
938
939
940
941
942
943
944







-
+







    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++;
    LastKnownRequestProcessed(display)++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return BadDrawable;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }
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
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28






-
-
-
-
+
+
+
+






+



+







/*
 * 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
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 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 "tkMacOSXConstants.h"
#include <dlfcn.h>
#include <objc/objc-auto.h>
#include <sys/stat.h>
#include <sys/utsname.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.
 */
37
38
39
40
41
42
43






































44
45
46
47
48
49
50
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#pragma mark TKApplication(TKInit)

@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macOSVersion = _macOSVersion;
@synthesize isDrawing = _isDrawing;
@synthesize needsToDraw = _needsToDraw;
@synthesize tkLiveResizeEnded = _tkLiveResizeEnded;
@synthesize tkPointerWindow = _tkPointerWindow;
- (void) setTkPointerWindow: (TkWindow *)winPtr
{
    if (winPtr) {
	Tcl_Preserve(winPtr);
    }
    if (_tkPointerWindow) {
	Tcl_Release(_tkPointerWindow);
    }
    _tkPointerWindow = winPtr;
    return;
}
@synthesize tkEventTarget = _tkEventTarget;
- (void) setTkEventTarget: (TkWindow *)winPtr
{
    if (winPtr) {
	Tcl_Preserve(winPtr);
    }
    if (_tkEventTarget) {
	Tcl_Release(_tkEventTarget);
    }
    _tkEventTarget = winPtr;
    return;
}
@synthesize tkDragTarget = _tkDragTarget;
- (void) setTkDragTarget: (TkWindow *)winPtr
{
    if (winPtr) {
	Tcl_Preserve(winPtr);
    }
    if (_tkDragTarget) {
	Tcl_Release(_tkDragTarget);
    }
    _tkDragTarget = winPtr;
    return;
}
@synthesize tkButtonState = _tkButtonState;
@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92










93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115







116
117
118
119
120
121
122
123

124
125
126
127
128


























129
130
131
132
133
134
135
136
137
138
139
140














141
142
143
144
145
146
147
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156





157
158



159
160
161
162
163
164
165
166
167
168





169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233







-
+

















+
+
+
+
+
+
+
+
+
+














-
-
-
-
-
+

-
-
-
+
+
+
+
+
+
+



-
-
-
-
-
+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












+
+
+
+
+
+
+
+
+
+
+
+
+
+







- (void) _unlockAutoreleasePool
{
    [self setPoolLock:[self poolLock] - 1];
}
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
- (void) _postedNotification: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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
}


/*
 * Fix for 10b38a7a7c.
 */

- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app
{
    return YES;
}

-(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];
    if ([NSApp macOSVersion] >= 110000) {

    /*
     * Initialize event processing.
     */
   /*
    * Initialize Apple Event processing. Apple's docs (see
    * https://developer.apple.com/documentation/appkit/nsapplication)
    * recommend doing this here, although historically we have
    * done this in applicationWillFinishLaunching. In response to
    * bug 7bb246b072.
    */

    TkMacOSXInitAppleEvents(_eventInterp);

    /*
     * Initialize the graphics context.
     */
    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);
    }
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{
    (void)notification;

   if ([NSApp macOSVersion] < 110000) {

   /*
    * Initialize Apple Event processing on macOS versions
    * older than Big Sur (11).
    */

    TkMacOSXInitAppleEvents(_eventInterp);

    }


    /*
     * Initialize the graphics context.
     */

    TkMacOSXUseAntialiasedText(_eventInterp, -1);
    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);

    /*
     * Construct the menu bar.
     */

    _defaultMainMenu = nil;
    [self _setupMenus];

    /*
     * 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];

    /*
     * Add an event monitor so we continue to receive NSMouseMoved and
     * NSMouseDragged events when the mouse moves outside of the key
     * window. The handler simply returns the events it receives, so
     * they can be processed in the same way as for other events.
     */

    [NSEvent addLocalMonitorForEventsMatchingMask:(NSMouseMovedMask |
						   NSLeftMouseDraggedMask)
	 handler:^NSEvent *(NSEvent *event)
	 {
	     return event;
	 }];

    /*
     * Process events to ensure that the root window is fully initialized. See
     * ticket 56a1823c73.
     */

    [NSApp _lockAutoreleasePool];
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177


178


















179
180
181
182
183
184
185
249
250
251
252
253
254
255
256
257
258
259
260
261
262


263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290







+






-
-
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    [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;
    majorVersion = (int)systemVersion.majorVersion;
    minorVersion = (int)systemVersion.minorVersion;
#endif

    if (majorVersion == 10 && minorVersion == 16) {

	/*
	 * If a program compiled with a macOS 10.XX SDK is run on macOS 11.0 or
	 * later then it will report majorVersion 10 and minorVersion 16, no
	 * matter what the actual OS version of the host may be. And of course
	 * Apple never released macOS 10.16. To work around this we guess the
	 * OS version from the kernel release number, as reported by uname.
	 */

	struct utsname name;
	char *endptr;
	if (uname(&name) == 0) {
	    majorVersion = (int)strtol(name.release, &endptr, 10) - 9;
	    minorVersion = 0;
	}
    }
    [NSApp setMacOSVersion: 10000*majorVersion + 100*minorVersion];

    /*
     * We are not drawing right now.
     */

    [NSApp setIsDrawing:NO];
198
199
200
201
202
203
204

205
206
207
208
209
210
211
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317







+







    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
						    @"CFBundleIconFile"];
    if (!iconFile) {
	NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
	if (path) {
	    NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
	    if (image) {
		[image setName:@"NSApplicationIcon"];
		[NSApp setApplicationIconImage:image];
		[image release];
	    }
	}
    }
}

322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442







-
+







     * 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. */
    exit((int)PTR2INT(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
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469







-
+







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.
     * The application initialization should only be done once.
     */

    if (!initialized) {
	struct stat st;
	Bool shouldOpenConsole = NO;
        Bool stdinIsNullish = (!isatty(0) &&
	    (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0)));
410
411
412
413
414
415
416
417

418
419
420
421
422
423
424
516
517
518
519
520
521
522

523
524
525
526
527
528
529
530







-
+







         * 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.
         * AppleEvent later, after the required procedure has been defined.
         */

	[NSApp _setup:interp];
	[NSApp finishLaunching];

        /*
         * Create a Tk event source based on the Appkit event queue.
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
652
653
654
655
656
657
658

659
660
661
662

663
664
665
666
667
668
669







-




-







    /*
     * 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);

Changes to macosx/tkMacOSXInt.h.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * tkMacOSXInt.h --
 *
 *	Declarations of Macintosh specific shared variables and procedures.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 _TKMACINT
#define _TKMACINT
95
96
97
98
99
100
101




102

103
104
105
106
107
108
109
110






111
112

113
114
115
116
117
118
119
120
121
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109





110
111
112
113
114
115
116

117


118
119
120
121
122
123
124







+
+
+
+
-
+



-
-
-
-
-
+
+
+
+
+
+

-
+
-
-







 * 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
 * GC CGColorRef cache for tkMacOSXColor.c
 * are in tkMacOSX.h.
 */

typedef struct {
    unsigned long cachedForeground;
    CGColorRef cachedForegroundColor;
    unsigned long cachedBackground;
    CGColorRef cachedBackgroundColor;
} TkpGCCache;
    Tk_MacOSXEmbedRegisterWinProc *registerWinProc;
    Tk_MacOSXEmbedGetGrafPortProc *getPortProc;
    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProc;
    Tk_MacOSXEmbedGetClipProc *getClipProc;
    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc;
} TkMacOSXEmbedHandler;

MODULE_SCOPE TkpGCCache *TkpGetGCCache(GC gc);
MODULE_SCOPE TkMacOSXEmbedHandler *tkMacOSXEmbedHandler;
MODULE_SCOPE void TkpInitGCCache(GC gc);
MODULE_SCOPE void TkpFreeGCCache(GC gc);

/*
 * Undef compatibility platform types defined above.
 */

#ifndef _TKMACPRIV
#   ifndef CGGEOMETRY_H_
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
174
175
176
177
178
179
180



181
182
183
184
185
186
187







-
-
-







/*
 * 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"
Changes to macosx/tkMacOSXKeyEvent.c.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17






-
-
-
-
+
+
+
+







/*
 * 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.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 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"
43
44
45
46
47
48
49
50

51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72












73
74
75
76
77
78
79
80
81
82
83
84
85




86
87
88
89
90
91
92
93
94
95
96



97
98
99
100
101
102
103

104
105
106
107
108
109
110
111






112
113

114


115
116
117
118
119
120
121
122
123
124
125
126
127

128
129

130
131
132
133
134
135
136
43
44
45
46
47
48
49

50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109


110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125


126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150

151
152
153
154
155
156
157
158







-
+





-
+
















+
+
+
+
+
+
+
+
+
+
+
+












-
+
+
+
+









-
-
+
+
+






-
+






-
-
+
+
+
+
+
+


+
-
+
+












-
+

-
+







#pragma mark TKApplication(TKKeyEvent)

@implementation TKApplication(TKKeyEvent)

- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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 virt = [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;
    }

    /*
     * Discard repeating KeyDown events if the repeat speed has been set to
     * "off" in System Preferences.  It is unclear why we get these, but we do.
     * See ticket [2ecb09d118].
     */

    if ([theEvent type] ==  NSKeyDown &&
	[theEvent isARepeat] &&
	[NSEvent keyRepeatDelay] < 0) {
            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;
	    winPtr = winPtr->dispPtr->focusPtr;
	    if (!winPtr) {
		return theEvent;
	    }
	    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];
	NSString *characters = [theEvent characters];
	if (characters.length > 0) {
	    keychar = [characters characterAtIndex:0];

	    /*
	     * Currently, real keys always send BMP characters, but who knows?
	     */

	    if (CFStringIsSurrogateHighCharacter(keychar)) {
		UniChar lowChar = [[theEvent characters] characterAtIndex:1];
		UniChar lowChar = [characters characterAtIndex:1];
		keychar = CFStringGetLongCharacterForSurrogatePair(
		    keychar, lowChar);
	    }
	} else {

	    /*
	     * This is a dead key, such as Option-e, so it should go to the
	     * TextInputClient.
	     * This is a dead key, such as Option-e, so it usually should get
	     * passed to the TextInputClient.  But if it has a Command modifier
	     * then it is not functioning as a dead key and should not be
	     * handled by the TextInputClient.  See ticket [1626ed65b8] and the
	     * method performKeyEquivalent which is implemented in
	     * tkMacOSXMenu.c.
	     */

	    if (!(modifiers & NSCommandKeyMask)) {
	    use_text_input = YES;
		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,
	      [self class], self, sel_getName(_cmd),
	      (type == NSKeyDown) && [theEvent isARepeat], modifiers, keychar,
	      virtual, w, type);
	      virt, 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
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247







-
+







    /*
     * 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;
    macKC.v.virt = virt;
    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
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299







-












-
+








    /*
     * 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;;
@synthesize tkNeedsDisplay = _tkNeedsDisplay;

/*
 * Implementation of the NSTextInputClient protocol.
 */

/* [NSTextInputClient inputText: replacementRange:] is called by
 * interpretKeyEvents when a composition sequence is complete.  It is also
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+







     * 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);
	TkSendVirtualEvent(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.
     *
345
346
347
348
349
350
351
352

353
354

355
356
357
358
359
360
361
366
367
368
369
370
371
372

373
374

375
376
377
378
379
380
381
382







-
+

-
+








	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;
	    macKC.v.virt = NON_BMP_VIRTUAL;
	} else if (repRange.location == 0 || sendingIMEText) {
	    macKC.v.virtual = REPLACEMENT_VIRTUAL;
	    macKC.v.virt = 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]) {
392
393
394
395
396
397
398



399
400
401
402
403
404
405
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429







+
+
+







 */

- (void)setMarkedText: (id)aString
	selectedRange: (NSRange)selRange
     replacementRange: (NSRange)repRange
{
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    if (!winPtr) {
	return;
    }
    Tk_Window focusWin = (Tk_Window)winPtr->dispPtr->focusPtr;
    NSString *temp;
    NSString *str;
    (void)selRange;

    str = ([aString isKindOfClass: [NSAttributedString class]]) ?
        [aString string] : aString;
428
429
430
431
432
433
434
435

436
437
438
439
440

441
442
443
444
445
446
447
452
453
454
455
456
457
458

459
460
461
462
463

464
465
466
467
468
469
470
471







-
+




-
+







	return;
    }

    /*
     * Use our insertText method to display the marked text.
     */

    Tk_SendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL);
    TkSendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL);
    processingCompose = YES;
    temp = [str copy];
    [self insertText: temp replacementRange:repRange];
    privateWorkingText = temp;
    Tk_SendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL);
    TkSendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL);
}

- (BOOL)hasMarkedText
{
    return privateWorkingText != nil;
}

502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
526
527
528
529
530
531
532

533
534
535
536
537
538
539
540







-
+







    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);
	TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
    }
}

- (NSArray *)validAttributesForMarkedText
{
    static NSArray *arr = nil;
    if (arr == nil) {
530
531
532
533
534
535
536

537
538
539
540
541
542
543
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568







+







    }
    return NSMakeRange(0, 0);
}

- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
{
    (void)thePoint;

    if (NS_KEYLOG) {
	TKLog(@"characterIndexForPoint request");
    }
    return NSNotFound;
}

- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
576
577
578
579
580
581
582
583

584
585
586
587
588
589
590
601
602
603
604
605
606
607

608
609
610
611
612
613
614
615







-
+







		  (unsigned long)[privateWorkingText length]);
	}

	[privateWorkingText release];
	privateWorkingText = nil;
	processingCompose = NO;
	if (composeWin) {
	    Tk_SendVirtualEvent(composeWin, "TkClearIMEMarkedText", NULL);
	    TkSendVirtualEvent(composeWin, "TkClearIMEMarkedText", NULL);
	}
    }
}

- (void)cancelComposingText
{
    if (NS_KEYLOG) {
600
601
602
603
604
605
606
607

608
609
610
611

612
613
614
615
616
617
618
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642
643
644







-
+




+







 * 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);
    Display *display;

    if (tkwin == NULL) {
	return;
    }
    display = Tk_Display(tkwin);
    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) |
644
645
646
647
648
649
650


651
652
653




654
655
656
657
658
659
660
670
671
672
673
674
675
676
677
678



679
680
681
682
683
684
685
686
687
688
689







+
+
-
-
-
+
+
+
+








    if (Tk_IsEmbedded(winPtr)) {
	TkWindow *contPtr = TkpGetOtherWindow(winPtr);
	if (Tk_IsTopLevel(contPtr)) {
	    local.x -= contPtr->wmInfoPtr->xInParent;
	    local.y -= contPtr->wmInfoPtr->yInParent;
	} else {
	    MacDrawable *topMacWin = TkMacOSXGetHostToplevel(winPtr);
	    if (topMacWin) {
	    TkWindow *topPtr = TkMacOSXGetHostToplevel(winPtr)->winPtr;
	    local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
	    local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
		TkWindow *topPtr = topMacWin->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;
701
702
703
704
705
706
707
708
709






710
711
712
713
714
715
716
730
731
732
733
734
735
736


737
738
739
740
741
742
743
744
745
746
747
748
749







-
-
+
+
+
+
+
+







    (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");
	    if (modalSession ) {
		if (keyboardGrabNSWindow == w) {
		    return GrabSuccess;
		} else {
		    Tcl_Panic("XGrabKeyboard: already grabbed");
		}
	    }
	    keyboardGrabNSWindow = w;
	    [w retain];
	    modalSession = [NSApp beginModalSessionForWindow:w];
	}
    }
    return GrabSuccess;
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
1
2
3
4
5




6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23





-
-
-
-
+
+
+
+






-
+







/*
 * 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
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 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 "tkMacOSXEvent.h"
#include "tkMacOSXConstants.h"
#include "tkMacOSXKeysyms.h"

/*
 * About keyboards
 * ---------------
 * Keyboards are complicated.  This long comment is an attempt to provide
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163







-
+









-
+







/*
 * 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,
			UInt16 keyaction, UInt32 virt, 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);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    keyboardChanged = YES;
    UpdateKeymaps();
}
@end

#pragma mark -
184
185
186
187
188
189
190
191

192
193
194

195
196
197
198
199

200
201
202
203
204
205
206
184
185
186
187
188
189
190

191
192
193

194
195
196
197
198

199
200
201
202
203
204
205
206







-
+


-
+




-
+







    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++) {
    for (kPtr = keyArray; kPtr->virt != 0; kPtr++) {
	MacKeycode macKC;
	macKC.v.o_s = 0;
	hPtr = Tcl_CreateHashEntry(&special2keysym, INT2PTR(kPtr->virtual),
	hPtr = Tcl_CreateHashEntry(&special2keysym, INT2PTR(kPtr->virt),
				   &dummy);
	Tcl_SetHashValue(hPtr, INT2PTR(kPtr->keysym));
	hPtr = Tcl_CreateHashEntry(&keysym2keycode, INT2PTR(kPtr->keysym),
				   &dummy);
	macKC.v.virtual = kPtr->virtual;
	macKC.v.virt = kPtr->virt;
	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.
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

272
273
274


275
276

277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
248
249
250
251
252
253
254

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

271
272


273
274
275

276
277
278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294







-
+















-
+

-
-
+
+

-
+










-
+







 */

static void
UpdateKeymaps()
{
    static Bool keymapInitialized = false;
    Tcl_HashEntry *hPtr;
    int virtual, index, dummy;
    int virt, 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++) {
        for (virt = 0; virt < 128; virt++) {
	    MacKeycode macKC;
	    macKC.v = (keycode_v) {.virtual = virtual, .o_s = index, .keychar = 0};
	    int modifiers = INDEX2CARBON(index), result;
	    macKC.v = (keycode_v) {.virt = virt, .o_s = index, .keychar = 0};
	    int modifiers = INDEX2CARBON(index);
	    UniChar keychar = 0;
	    result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, virtual,
	    KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, virt,
				      modifiers, NULL);
	    if (keychar == 0x10) {

		/*
		 * This is a special key, handled in InitHashTables.
		 */

		continue;
	    }
	    macKC.v.keychar = keychar;
	    if (! ON_KEYPAD(virtual)) {
	    if (! ON_KEYPAD(virt)) {
		hPtr = Tcl_CreateHashEntry(&unichar2xvirtual,
					   INT2PTR(macKC.x.keychar), &dummy);
		Tcl_SetHashValue(hPtr, INT2PTR(macKC.x.xvirtual));
            }
	    xvirtual2unichar[macKC.x.xvirtual] = macKC.x.keychar;
	}
    }
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336







-
+









static int
KeyDataToUnicode(
    UniChar *uniChars,
    int maxChars,
    UInt16 keyaction,
    UInt32 virtual,
    UInt32 virt,
    UInt32 modifiers,
    UInt32 *deadKeyStatePtr)
{
    static const void *layoutData = NULL;
    static UInt32 keyboardType = 0;
    UniCharCount actuallength = 0;

351
352
353
354
355
356
357
358

359
360
361
362
363
364
365

366
367
368
369
370
371
372
351
352
353
354
355
356
357

358
359
360
361
362
363
364

365
366
367
368
369
370
371
372







-
+






-
+







	keyboardChanged = 0;
    }
    if (layoutData) {
	OptionBits options = 0;
	UInt32 dummyState;
	OSStatus err;

	virtual &= 0xFF;
	virt &= 0xFF;
	modifiers = (modifiers >> 8) & 0xFF;
	if (!deadKeyStatePtr) {
	    options = kUCKeyTranslateNoDeadKeysMask;
	    dummyState = 0;
	    deadKeyStatePtr = &dummyState;
	}
	err = ChkErr(UCKeyTranslate, layoutData, virtual, keyaction, modifiers,
	err = ChkErr(UCKeyTranslate, (const UCKeyboardLayout *)layoutData, virt, keyaction, modifiers,
		keyboardType, options, deadKeyStatePtr, maxChars,
		&actuallength, uniChars);
	if (!actuallength && *deadKeyStatePtr) {

	    /*
	     * We are waiting for another key.
	     */
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
470
471
472
473
474
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
460
461
462
463
464
465
466

467
468
469
470
471
472
473
474







-
+










-
+














-
+













-
+







    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));
    hPtr = Tcl_FindHashEntry(&special2keysym, INT2PTR(macKC.v.virt));
    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) {
    if (macKC.v.virt > 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,
    result = KeyDataToUnicode(&keychar, 1, kUCKeyActionDown, macKC.v.virt,
			      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,
    KeyCode keycode,
    int index)
{
    return XkbKeycodeToKeysym(NULL, keycode, 0, index);
}

/*
 *----------------------------------------------------------------------
633
634
635
636
637
638
639
640

641
642
643
644
645
646
647
648

649
650
651
652
653
654
655
633
634
635
636
637
638
639

640
641
642
643
644
645
646
647

648
649
650
651
652
653
654
655







-
+







-
+








    /*
     * First check for a special key.
     */

    hPtr = Tcl_FindHashEntry(&keysym2keycode, INT2PTR(keysym));
    if (hPtr != NULL) {
	return (KeyCode) Tcl_GetHashValue(hPtr);
	return (KeyCode) PTR2INT(Tcl_GetHashValue(hPtr));
    }

    /*
     * Initialize the keycode as if the keysym cannot be converted to anything
     * else.
     */

    macKC.v.virtual = NO_VIRTUAL;
    macKC.v.virt = 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.
     */
715
716
717
718
719
720
721
722

723
724
725
726
727
728
729
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729







-
+








	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) {
	    if (macKC.v.virt != 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;
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791







-
+







    }

    /*
     * Modifier key events have a special mac keycode (see tkProcessKeyEvent).
     */

    if (macKC.v.keychar == MOD_KEYCHAR) {
	switch (macKC.v.virtual) {
	switch (macKC.v.virt) {
	case 54:
	    return XK_Meta_R;
	case 55:
	    return XK_Meta_L;
	case 56:
	    return XK_Shift_L;
	case 57:
949
950
951
952
953
954
955
956

957
958
959
960
961
962
963
964
965
966
967
949
950
951
952
953
954
955

956
957
958
959
960
961
962
963
964
965
966
967







-
+












    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;
	macKC.v.virt = NO_VIRTUAL;
    }
    return macKC.uint;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
Changes to macosx/tkMacOSXKeysyms.h.
1
2
3
4
5
6
7
8
9
10
11





12
13
14
15
16
17
18
1
2
3
4
5
6





7
8
9
10
11
12
13
14
15
16
17
18






-
-
-
-
-
+
+
+
+
+







/*
 * 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
 * Copyright © 1990-1994 The Regents of the University of California.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 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
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58







-
+
















-
+







 * 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] */
    int virt;	/* 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},
    {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,	'+'},
81
82
83
84
85
86
87
88

89
90
91
92
93

94
95
96
97
98

99
100
101
102
103
104
105
81
82
83
84
85
86
87

88
89
90
91
92

93
94
95
96
97

98
99
100
101
102
103
104
105







-
+




-
+




-
+







    {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},
    {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 */
    {116,	XK_Prior,	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 */
    {121,	XK_Next,	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}
};
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151







-
+







 */

typedef struct KeysymInfo {
    KeySym keysym;
    KeyCode keycode;
} KeysymInfo;

const KeysymInfo keysymTable[] = {
static const KeysymInfo keysymTable[] = {
    {0x0020, 0x0020}, /* space */
    {0x0021, 0x0021}, /* exclam */
    {0x0022, 0x0022}, /* quotedbl */
    {0x0023, 0x0023}, /* numbersign */
    {0x0024, 0x0024}, /* dollar */
    {0x0025, 0x0025}, /* percent */
    {0x0026, 0x0026}, /* ampersand */
680
681
682
683
684
685
686
687

688
689
690
691
692
693
694
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694







-
+







    {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 */
    {0x07cb, 0x039b}, /* Greek_LAMBDA */
    {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 */
Changes to macosx/tkMacOSXMenu.c.
1
2
3
4
5
6
7
8
9




10
11
12
13
14
15
16
1
2
3
4
5




6
7
8
9
10
11
12
13
14
15
16





-
-
-
-
+
+
+
+







/*
 * tkMacOSXMenu.c --
 *
 *	This module implements the Mac-platform specific features of menus.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2012 Adrian Robert.
 * Copyright © 1996-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2012 Adrian Robert.
 *
 * 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 "tkMenubutton.h"
87
88
89
90
91
92
93



94

95
96
97
98
99
100
101
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104







+
+
+
-
+







    ACCEL(Power,	0x233d),
    ACCEL(Eject,	0xf804),
    {NULL, 0, 0}
};
#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 Bool   inPostMenu = false;
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);
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+







 * 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
 * The TKBackgroundLoop 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].
 */

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
163
164
165
166
167
168
169

170
171
172
173
174
175
176







-







    }
    [pool drain];
}
@end

TKBackgroundLoop *backgroundLoop = nil;


#pragma mark TKMenu

/*
 * This interface is not declared in tkMacOSXPrivate.h because it requires
 * tkMenu.h.
 */

185
186
187
188
189
190
191







































192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212


213
214
215
216
217
218
219
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251


252
253
254
255
256
257
258
259
260







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



















-
-
+
+







    NSAssert(!_tkSpecial, @"Cannot change specialness of a special menu");
    _tkSpecial = special;
}
- (BOOL) isSpecial: (NSUInteger) special
{
    return (_tkSpecial == special);
}

/*
 * There are cases where a KeyEquivalent (aka menu accelerator) is defined for
 * a "dead key", i.e. a key which does not have an associated character but is
 * only meant to be the start of a composition sequence.  For example, on a
 * Spanish keyboard both the ' and the ` keys are dead keys used to place
 * accents over letters.  But ⌘` is a standard KeyEquivalent which cycles
 * through the open windows of an application, changing the focus to the next
 * window. This caused a bug reported in [1626ed65b8].  When a dead key that is
 * also as a KeyEquivalent is pressed, a KeyDown event with no characters would
 * be passed to performKeyEquivalent.  The default implementation provided by
 * Apple would cause that event to be routed to some private methods of NSMenu
 * which raise NSInvalidArgumentException, causing an abort. Returning NO in
 * such a case prevents the abort.  So the override below returns NO when the
 * event has no characters.
 *
 * In fact, however, we never want to handle accelerators because they are
 * handled by Tk.  Hence this method could always return NO.  But if we did
 * that then we would not see the menu flash when an accelerator is pressed.
 * The flash is a useful visual indicator. It turns out that the flash is an
 * undocumented side effect of calling the super method for
 * performKeyEquivalent.  The super method also calls the NSMenuItem's action
 * method - tkMenuItemInvoke in our case.  This is also not documented.
 *
 * To enable the flash we set up a flag that tells the action method to do
 * nothing, because it is being called by an accelerator. The override below
 * sets the flag and then calls super. See ticket [ead70921a9].
 */

static Bool runMenuCommand = true;
- (BOOL)performKeyEquivalent:(NSEvent *)event
{
    if ([[event characters] length] == 0) {
	return NO;
    }
    runMenuCommand = false;
    /* Make the menu flash and call tkMenuItemInvoke. */
    return [super performKeyEquivalent: event];
}
@end

@implementation TKMenu(TKMenuPrivate)

- (id) initWithTitle: (NSString *) aTitle
{
    self = [super initWithTitle:aTitle];
    if (self) {
	_tkMenu = NULL;
	_tkOffset = 0;
	_tkItemCount = 0;
	_tkSpecial = 0;
	[self setDelegate:self];
    }
    return self;
}

- (id) initWithTkMenu: (TkMenu *) tkMenu
{
    NSString *title = [[NSString alloc] initWithUTF8String:
	    Tk_PathName(tkMenu->tkwin)];
    NSString *title = [[TKNSString alloc] initWithTclUtfBytes:
	    Tk_PathName(tkMenu->tkwin) length:-1];

    self = [self initWithTitle:title];
    [title release];
    if (self) {
	_tkMenu = tkMenu;
    }
    return self;
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284







-
+







    copy->_tkItemCount = _tkItemCount;
    copy->_tkSpecial = _tkSpecial;
    return copy;
}

- (TkMenu *) tkMenu
{
    return _tkMenu;
    return (TkMenu *)_tkMenu;
}

- (int) tkIndexOfItem: (NSMenuItem *) menuItem
{
    return [self indexOfItem:menuItem] - _tkOffset;
}

297
298
299
300
301
302
303


304
305
306
307











308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
338
339
340
341
342
343
344
345
346




347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366







367
368

369

370
371
372
373
374
375
376







+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-









-
-
-
-
-
-
-


-

-







- (BOOL)worksWhenModal
{
    return YES;
}

- (void) tkMenuItemInvoke: (id) sender
{
    if (!runMenuCommand) {

    /*
     * 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
    	/*
    	 * We are being called for a menu accelerator.  Tk will handle it.
    	 * Just update the runMenuCommand flag.
    	 */

    	runMenuCommand = true;
    	return;
    }

    /*
     * We are being called for an actual menu item selection; run the command.
     * 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);
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466







-
+







}

- (void) menuDidClose: (NSMenu *) menu
{
    (void)menu;

    if (_tkMenu) {
	RecursivelyClearActiveMenu(_tkMenu);
	RecursivelyClearActiveMenu((TkMenu *)_tkMenu);
    }
}

- (void) menu: (NSMenu *) menu willHighlightItem: (NSMenuItem *) item
{
    (void)menu;

436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
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
476
477
478
479
480
481
482

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







-
+



















-
+







-
-
+
+
+
+
+
+
+






-
+













+
+
+
+








    if (menuPtr) {
	Tcl_Interp *interp = menuPtr->interp;

	Tcl_Preserve(interp);
	Tcl_Preserve(menuPtr);

	int result = TkPostCommand(_tkMenu);
	int result = TkPostCommand(menuPtr);

	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);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
    }
    backgroundLoop = [[TKBackgroundLoop alloc] init];
    [backgroundLoop start];
    //TkMacOSXClearMenubarActive();
    //TkMacOSXPreprocessMenu();

    /*
     * Make sure that we can run commands when actually using a menu.
     * See [412b80fcaf].
     */

    runMenuCommand = true;
}

- (void) menuEndTracking: (NSNotification *) notification
{
    (void)notification;
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (backgroundLoop) {
	[backgroundLoop cancel];
	[backgroundLoop release];
	backgroundLoop = nil;
    }
    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]) {
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
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







-


-
-
+
+
-
-
-
-
-
-
-
-
-
-
-





-
+







-
-
+
-




+
-
-
+
+







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+

+
-
+




















-
+











-
-
-
+
+
+
+
+


-
-
-
+
-

-
+
-
-
-
-
-
-
-
-
-
+
-







    NSMenuItem *menuItem = (NSMenuItem *) mePtr->platformEntryData;
    NSString *title = @"";
    NSAttributedString *attributedTitle = nil;
    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);
    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) {
    } else if (mePtr->bitmapPtr != NULL) {
	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];
	[image setTemplate:YES];
	}
    }
    [menuItem setImage:image];
    if ((!image || mePtr->compound != COMPOUND_NONE) && mePtr->labelPtr &&
	    mePtr->labelLength) {
	title = [[[TKNSString alloc]
	title = [[[NSString alloc] initWithBytes:Tcl_GetString(mePtr->labelPtr)
		length:mePtr->labelLength encoding:NSUTF8StringEncoding]
		    initWithTclUtfBytes:Tcl_GetString(mePtr->labelPtr)
				length:mePtr->labelLength]
		autorelease];
	if ([title hasSuffix:@"..."]) {
	    title = [NSString stringWithFormat:@"%@%C",
		    [title substringToIndex:[title length] - 3], 0x2026];
	}
    }
    [menuItem setTitle:title];
    if (strcmp(Tcl_GetString(fontPtr), "menu") || gc->foreground != defaultFg
	    || gc->background != defaultBg) {
	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);


#if 0

    /*
     * The -background and -foreground options are now ignored in Aqua.
     * See ticket [635167af14].
     */

    NSDictionary fontAttributes = TkMacOSXNSFontAttributesForFont(
	Tk_GetFontFromObj(mePtr->menuPtr->tkwin, fontPtr));
    NSMutableDictionary *attributes = [fontAttributes mutableCopy];
    static unsigned long defaultBg = 0, defaultFg = 0;
    if (defaultBg == 0) {
	tkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_BG_COLOR);
	defaultBg = tkColPtr->color.pixel;
	ckfree(tkColPtr);
    }
    if (defaultFg == 0) {
	tkColor *tkColPtr = TkpGetColor(NULL, DEF_MENU_FG);
	defaultFg = tkColPtr->color.pixel;
	ckfree(tkColPtr);
    }
    if (gc->foreground != defaultFg) {
	NSColor *fgcolor = TkMacOSXGetNSColor(gc, gc->foreground);
	[attributes setObject:fgcolor
		       forKey:NSForegroundColorAttributeName];
    }
	    attributes = [[attributes mutableCopy] autorelease];
	    [(NSMutableDictionary *) attributes setObject:color
		    forKey:NSForegroundColorAttributeName];
	}
	if (attributes) {
	    attributedTitle = [[[NSAttributedString alloc]
    if (gc->background != defaultBg) {
	NSColor *bgcolor = TkMacOSXGetNSColor(gc, gc->background);
	[attributes setObject:bgcolor
	 	       forKey:NSBackgroundColorAttributeName];
    }

#else

		    initWithString:title attributes:attributes] autorelease];
	}
    }
    NSDictionary *attributes = TkMacOSXNSFontAttributesForFont(
	Tk_GetFontFromObj(mePtr->menuPtr->tkwin, fontPtr));

#endif

    attributedTitle = [[NSAttributedString alloc] initWithString:title
	attributes:attributes];
    [menuItem setAttributedTitle:attributedTitle];
    [attributedTitle release];
    [menuItem setEnabled:!(mePtr->state == ENTRY_DISABLED)];
    [menuItem setEnabled:(mePtr->state != ENTRY_DISABLED)];
    [menuItem setState:((mePtr->type == CHECK_BUTTON_ENTRY ||
	    mePtr->type == RADIO_BUTTON_ENTRY) && mePtr->indicatorOn &&
	    (mePtr->entryFlags & ENTRY_SELECTED) ? NSOnState : NSOffState)];
    if (mePtr->type != CASCADE_ENTRY && mePtr->accelPtr && mePtr->accelLength) {
	keyEquivalent = ParseAccelerator(Tcl_GetString(mePtr->accelPtr),
		&modifierMask);
    }
    [menuItem setKeyEquivalent:keyEquivalent];
    [menuItem setKeyEquivalentModifierMask:modifierMask];
    if (mePtr->type == CASCADE_ENTRY && mePtr->namePtr) {
	TkMenuReferences *menuRefPtr;

	menuRefPtr = TkFindMenuReferencesObj(mePtr->menuPtr->interp,
		mePtr->namePtr);
	if (menuRefPtr && menuRefPtr->menuPtr) {
	    CheckForSpecialMenu(menuRefPtr->menuPtr);
	    submenu = (TKMenu *) menuRefPtr->menuPtr->platformData;
	    if ([submenu supermenu] && [menuItem submenu] != submenu) {
		/*
		 * This happens during a clone, where the parent menu is
		 * cloned before its children, so just ignore this temprary
		 * cloned before its children, so just ignore this temporary
		 * setting, it will be changed shortly (c.f. tkMenu.c
		 * CloneMenu())
		 */

		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.
		     * This menuItem might have been previously disabled which
		     * would have disabled all of its entries; we must re-enable the
		     * entries here.  It is important to iterate though the Tk
		     * entries, not the NSMenuItems, since some NSMenuItems may
		     * have been added by the system.  See [7185d26cf4].
		     */

		    int i = 0;
		    NSArray *itemArray = [submenu itemArray];

		    for (int i = 0; i < menuRefPtr->menuPtr->numEntries; i++) {
		    for (NSMenuItem *item in itemArray) {
			TkMenuEntry *submePtr = menuRefPtr->menuPtr->entries[i];

			NSMenuItem *item = (NSMenuItem *) submePtr->platformEntryData;
			/*
			 * 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)];
			[item setEnabled:(submePtr->state != ENTRY_DISABLED)];
			i++;
		    }
		}
	    }
	}
    }
    [menuItem setSubmenu:submenu];

832
833
834
835
836
837
838
839

840
841


842

843
844
845
846





847
848
849
850
851
852
853
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







-
+
-

+
+
-
+

-
-
-
+
+
+
+
+







TkpDestroyMenuEntry(
    TkMenuEntry *mePtr)
{
    NSMenuItem *menuItem;
    TKMenu *menu;
    NSInteger index;

    if (mePtr->platformEntryData && mePtr->menuPtr->platformData) {
    if (mePtr->platformEntryData) {
	menu = (TKMenu *) mePtr->menuPtr->platformData;
	menuItem = (NSMenuItem *) mePtr->platformEntryData;
	if (mePtr->menuPtr->platformData) {
	    menu = (TKMenu *) mePtr->menuPtr->platformData;
	index = [menu indexOfItem:menuItem];
	    index = [menu indexOfItem:menuItem];

	if (index > -1) {
	    [menu removeItemAtIndex:index];
	}
	    if (index > -1) {
		[menu removeItemAtIndex:index];
	    }
	}
	[menuItem setTag:(NSInteger) NULL];
	[menuItem release];
	mePtr->platformEntryData = NULL;
    }
}

/*
 *----------------------------------------------------------------------
904
905
906
907
908
909
910
911

912
913
914

915
916
917
918
919
920
921
959
960
961
962
963
964
965

966
967
968

969
970
971
972
973
974
975
976







-
+


-
+







    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;
    inPostMenu = true;
    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
        inPostMenu = 0;
        inPostMenu = false;
        return result;
    }
    if (itemIndex >= numItems) {
    	itemIndex = numItems - 1;
    }
    if (itemIndex >= 0) {
	item = [menu itemAtIndex:itemIndex];
929
930
931
932
933
934
935
936

937
938
939
940
941
942
943
984
985
986
987
988
989
990

991
992
993
994
995
996
997
998







-
+







    if (menuPtr->tkwin == NULL) {
    	return TCL_OK;
    }

    [menu popUpMenuPositioningItem:item
			atLocation:[win tkConvertPointFromScreen:location]
			    inView:view];
    inPostMenu = 0;
    inPostMenu = false;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpPostTearoffMenu --
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
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







-
-
-
-
-
-
-















+
+
+
+
+
+
+
+
+
+
+
+







    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 menu y position so that the specified entry will be located
     * at the given coordinates.
     */

    if (index < 0 || index >= menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 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
1111
1112
1113
1114
1115
1116
1117
1118
1119


1120
1121
1122
1123
1124
1125
1126
1171
1172
1173
1174
1175
1176
1177


1178
1179
1180
1181
1182
1183
1184
1185
1186







-
-
+
+







    }

    if (menuName) {
	Tk_Window menubar = NULL;

	if (winPtr->wmInfoPtr &&
		winPtr->wmInfoPtr->menuPtr &&
		winPtr->wmInfoPtr->menuPtr->mainMenuPtr) {
	    menubar = winPtr->wmInfoPtr->menuPtr->mainMenuPtr->tkwin;
		winPtr->wmInfoPtr->menuPtr->masterMenuPtr) {
	    menubar = winPtr->wmInfoPtr->menuPtr->masterMenuPtr->tkwin;
	}

	/*
	 * Attempt to find the NSMenu directly.  If that fails, ask Tk to find
	 * it.
	 */

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
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







-
+






-
-
+
+









-
+







 *----------------------------------------------------------------------
 */

static void
CheckForSpecialMenu(
    TkMenu *menuPtr)		/* The menu we are checking */
{
    if (!menuPtr->mainMenuPtr->tkwin) {
    if (!menuPtr->masterMenuPtr->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;
		&& cascadeEntryPtr->menuPtr->masterMenuPtr->tkwin) {
	    TkMenu *mainMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
	    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) {
			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++;
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
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







-
+









-
+







	    }
	    i++;
	}
    }
    if (ch) {
	return [[[NSString alloc] initWithCharacters:&ch length:1] autorelease];
    } else {
	return [[[[NSString alloc] initWithUTF8String:accel] autorelease]
	return [[[[TKNSString alloc] initWithTclUtfBytes:accel length:-1] autorelease]
		lowercaseString];
    }
}

/*
 *--------------------------------------------------------------
 *
 * ModifierCharWidth --
 *
 *	Helper mesuring width of command char in given font.
 *	Helper measuring width of command char in given font.
 *
 * Results:
 *	Width of command char.
 *
 * Side effects:
 *	None.
 *
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
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







-
+












-
+








void
TkpComputeStandardMenuGeometry(
    TkMenu *menuPtr)		/* Structure describing menu. */
{
    NSSize menuSize;
    Tk_Font tkfont, menuFont;
    Tk_FontMetrics menuMetrics, entryMetrics, *fmPtr;
    Tk_FontMetrics menuMetrics, entryMetrics;
    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) {
    if (menuPtr->tkwin == NULL || menuPtr->masterMenuPtr != menuPtr) {
	return;
    }

    menuSize = [(NSMenu *) menuPtr->platformData size];
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr,
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1445
1446
1447
1448
1449
1450
1451

1452
1453
1454
1455

1456
1457
1458
1459
1460
1461
1462







-




-







    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 {
	    /*
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
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







-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+


-
+

-
+







 *----------------------------------------------------------------------
 */

void
MenuSelectEvent(
    TkMenu *menuPtr)		/* the menu we have selected. */
{
    XVirtualEvent event;
    union {XEvent general; XVirtualEvent virt;} event;

    bzero(&event, sizeof(XVirtualEvent));
    event.type = VirtualEvent;
    event.serial = LastKnownRequestProcessed(menuPtr->display);
    event.send_event = false;
    event.display = menuPtr->display;
    event.event = Tk_WindowId(menuPtr->tkwin);
    event.root = XRootWindow(menuPtr->display, 0);
    event.subwindow = None;
    event.time = TkpGetMS();
    XQueryPointer(NULL, None, NULL, NULL, &event.x_root, &event.y_root, NULL,
	    NULL, &event.state);
    event.same_screen = true;
    event.name = Tk_GetUid("MenuSelect");
    bzero(&event, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = LastKnownRequestProcessed(menuPtr->display);
    event.virt.send_event = false;
    event.virt.display = menuPtr->display;
    event.virt.event = Tk_WindowId(menuPtr->tkwin);
    event.virt.root = XRootWindow(menuPtr->display, 0);
    event.virt.subwindow = None;
    event.virt.time = TkpGetMS();
    XQueryPointer(NULL, None, NULL, NULL, &event.virt.x_root, &event.virt.y_root, NULL,
	    NULL, &event.virt.state);
    event.virt.same_screen = true;
    event.virt.name = Tk_GetUid("MenuSelect");
    Tk_MakeWindowExist(menuPtr->tkwin);
    if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {
	Tk_HandleEvent((XEvent *) &event);
	Tk_HandleEvent(&event.general);
    } else {
	Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
	Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * RecursivelyClearActiveMenu --
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
















-
-







	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * 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
1811
1812
1813
1814
1815
1816
1817
1818





1819
1820
1821
1822
1823
1824

1825
1826
1827
1828
1829
1830
1831
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







-
+
+
+
+
+





-
+








/*
 *----------------------------------------------------------------------
 *
 * TkpDrawMenuEntry --
 *
 *	Draws the given menu entry at the given coordinates with the given
 *	attributes.
 *	attributes.  This is a no-op on macOS since the menus are drawn by
 *      the Apple window manager, which also handles all events related to
 *      selecting menu items.  This function is only called for tearoff
 *      menus, which are not supported on macOS but do get drawn as nearly
 *      invisible 1 pixel wide windows on macOS
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	X Server commands are executed to display the menu entry.
 *	None
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawMenuEntry(
    TCL_UNUSED(TkMenuEntry *),		/* The entry to draw */
Changes to macosx/tkMacOSXMenubutton.c.
1
2
3
4
5
6
7
8
9
10
11





12
13
14
15
16
17
18
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.
 * Copyright © 1996 Sun Microsystems, Inc.
 * Copyright © 2001 Apple Computer, Inc.
 * Copyright © 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"
161
162
163
164
165
166
167
168
169


170
171
172
173
174
175
176
161
162
163
164
165
166
167


168
169
170
171
172
173
174
175
176







-
-
+
+







 *----------------------------------------------------------------------
 */

void
TkpDisplayMenuButton(
    ClientData clientData)	/* Information about widget. */
{
    MacMenuButton *mbPtr = clientData;
    TkMenuButton *butPtr = clientData;
    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;
236
237
238
239
240
241
242
243
244


245
246
247
248
249
250
251
236
237
238
239
240
241
242


243
244
245
246
247
248
249
250
251







-
-
+
+







 * Side effects:
 *	The menu button's window may change size.
 *
 *----------------------------------------------------------------------
 */

void
TkpComputeMenuButtonGeometry(butPtr)
    TkMenuButton *butPtr;	/* Widget record for menu button. */
TkpComputeMenuButtonGeometry(
    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;

    /*
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
371
372
373
374
375
376
377

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397



398
399
400
401
402
403
404







-




















-
-
-







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;
685
686
687
688
689
690
691
692
693


694
695
696
697
698
699
700
681
682
683
684
685
686
687


688
689
690
691
692
693
694
695
696







-
-
+
+







 */

static void
MenuButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *buttonPtr = clientData;
    MacMenuButton *mbPtr = clientData;
    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) {
Changes to macosx/tkMacOSXMenus.c.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * tkMacOSXMenus.c --
 *
 *	These calls set up the default menus for Tk.
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 "tkMenu.h"
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
195
196
197
198
199
200
201


202
203

204
205
206
207
208
209
210
211







-
-


-
+







    } else {
        return [super validateUserInterfaceItem:anItem];
    }
}

- (void) orderFrontStandardAboutPanel: (id) sender
{
    (void)sender;

    if (!_eventInterp || !Tcl_FindCommand(_eventInterp, "tkAboutDialog",
	    NULL, 0) || (GetCurrentEventKeyModifiers() & optionKey)) {
	TkAboutDlg();
	[super orderFrontStandardAboutPanel:nil];
    } else {
	int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", -1,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
227
228
229
230
231
232
233


234
235
236
237
238
239
240







-
-







	}
	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;

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
252
253
254
255
256
257
258


259
260
261
262
263
264
265







-
-







	}
	Tcl_ResetResult(_eventInterp);
    }
}

- (void) tkDemo: (id) sender
{
	(void)sender;

    if (_eventInterp) {
	Tcl_Obj *path = GetWidgetDemoPath(_eventInterp);

	if (path) {
	    Tcl_IncrRefCount(path);

	    [_demoMenuItem setHidden:YES];
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
277
278
279
280
281
282
283


284
285
286
287
288
289
290







-
-








#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]]) { \
326
327
328
329
330
331
332
333

334
335
336
337




338
339
340
341






342
343
344



345
346
347
348
349
350
351
318
319
320
321
322
323
324

325
326



327
328
329
330
331



332
333
334
335
336
337
338


339
340
341
342
343
344
345
346
347
348







-
+

-
-
-
+
+
+
+

-
-
-
+
+
+
+
+
+

-
-
+
+
+







 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetWidgetDemoPath(
    Tcl_Interp *interp)
{
    Tcl_Obj *result = NULL;
    Tcl_Obj *libpath, *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_GetVar2Ex(interp, "tk_library", NULL, TCL_GLOBAL_ONLY);
    if (libpath) {
	Tcl_Obj *demo[2] = {	Tcl_NewStringObj("demos", 5),
				Tcl_NewStringObj("widget", 6) };

	libpath = Tcl_GetObjResult(interp);
	Tcl_IncrRefCount(libpath);
	result = Tcl_FSJoinToPath(libpath, 1, demo);
	Tcl_IncrRefCount(libpath);
	Tcl_IncrRefCount(demo[0]);
	Tcl_IncrRefCount(demo[1]);
	result = Tcl_FSJoinToPath(libpath, 2, demo);
	Tcl_DecrRefCount(demo[1]);
	Tcl_DecrRefCount(demo[0]);
	Tcl_DecrRefCount(libpath);
    }
    Tcl_ResetResult(interp);
    } 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
356
357
358
359
360
361
362



363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398







-
-
-
+
+
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXHandleMenuSelect(
    TCL_UNUSED(short),
    TCL_UNUSED(unsigned short),
    TCL_UNUSED(int))
    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
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414









415
416
417
418
419
420





421
422
423
424
425
426
427
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
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 void
GenerateEditEvent(
    const char *name)
{
    XVirtualEvent event;
    union {XEvent general; XVirtualEvent virt;} 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();
    bzero(&event, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.virt.send_event = false;
    event.virt.display = Tk_Display(tkwin);
    event.virt.event = Tk_WindowId(tkwin);
    event.virt.root = XRootWindow(Tk_Display(tkwin), 0);
    event.virt.subwindow = None;
    event.virt.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);
	    &event.virt.x_root, &event.virt.y_root, &x, &y, &event.virt.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.virt.x, &event.virt.y);
    event.virt.same_screen = true;
    event.virt.name = Tk_GetUid(name);
    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

#pragma mark -

#pragma mark NSMenu & NSMenuItem Utilities

@implementation NSMenu(TKUtils)
Changes to macosx/tkMacOSXMouseEvent.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
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


32
33
34
35
36
37
38
39
40



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84

85
86
87
88

89
90
91
92
93
94
95

96
97
98
99
100

101
102
103
104




105
106
107
108
109
110
111
112





113
114
115
116
117
118


119
120
121



122
123
124



125
126
127
128
129



130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158

159


160
161
162
163
164
165



166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

305


306
307




308
309
310
311







312


313
314
315

316

317
318
319









320
321

322




323





324



325
326




327





328


329

330
331
332

333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363









364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381




382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414

415
416
417

418
419
420
421




422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448


449
450
451
452
453
454
455

456
457
458
459
460

461
462
463
464
465
466
467






-
-
+
+







-
+















-
-









-
-
-
+
+
+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+




-
+

+
-
+



-
+


+
+
+
+
-
+
+
+


-
+



-
-
-
-
+
+
+
+
+
+


-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
+

-
-
-



-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+


-
+


-
+
-
-
+

+
+


-
-
-
+
+
+
+
+
+
+
+
+

-
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+

+
+
+
+
+
+
+
+
+
+











-
+
-
-


-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
-
-
+
+

-
+
-
+
+

-
-
-
-
-
-
-
-
-

+
-
+
-
-
-
-
+
-
-
-
-
-
+
-
-
-
+
+
-
-
-
-

-
-
-
-
-
+
-
-
+
-



-
+
+





+





-
+










-
+






-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+






-



-
+



-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
+
+
+




-
+




-







/*
 * tkMacOSXMouseEvent.c --
 *
 *	This file implements functions that decode & handle mouse events on
 *	MacOS X.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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"
#include "tkMacOSXInt.h"
#include "tkMacOSXEvent.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
 * window attribute pointing to the key 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.
 */

/* The basic job of tkProcessMouseEvent is to generate a call to
 * Tk_UpdatePointer.  That function receives a Tk_Window which (ignoring cases
 * when a grab is in effect) should be the highest window within the focused
 * toplevel that contains the pointer, as well as the pointer location in
 * screen coordinates and the current button state.  Tk maintains a cache of
 * these three values.  A change in any of these values causes Tk_UpdatePointer
 * to generate, respectively, Enter/Leave events, or Motion events, or
 * button Press/Release events. The Tk_Window value is allowed to be NULL,
 * which indicates that the pointer is not in the focused toplevel.
 *
 * Enter or Leave events for toplevel windows are generated when the Tk_Window
 * value changes to or from NULL.  This is problematic on macOS due to the fact
 * that Tk_UpdatePointer does not generate Motion events when the Tk_Window
 * value is NULL.  A consequence of this is that Tk_UpdatePointer will either
 * fail to generate correct Enter/Leave events for toplevels or else be unable
 * to generate Motion events when the pointer is outside of the focus window.
 * It is important to be able to generate such events because otherwise a
 * scrollbar on the edge of a toplevel becomes unusable.  Any time that the
 * pointer wanders out of the window during a scroll, the scroll will stop.
 * That is an extremely annoying and unexpected behavior.  Much of the code in
 * this module, including the trickiest parts, is devoted to working around
 * this problem.  The other tricky parts are related to transcribing Apple's
 * NSMouseEntered, NSMouseExited, and NSLeftMouseDragged events into a form
 * that makes sense to Tk.
 */


@implementation TKApplication(TKMouseEvent)

- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
    NSWindow *eventWindow = [theEvent window];
    NSEventType eventType = [theEvent type];
    NSRect viewFrame = [[eventWindow contentView] frame];
    TKContentView *contentView = [eventWindow contentView];
    NSPoint location = [theEvent locationInWindow];
    NSPoint viewLocation = [contentView convertPoint:location fromView:nil];
    TkWindow *winPtr = NULL, *grabWinPtr;
    TkWindow *winPtr = NULL, *grabWinPtr, *scrollTarget = NULL;
    Tk_Window tkwin = NULL, capture, target;
    NSPoint local, global;
    NSInteger button;
    Bool inTitleBar = NO;
    TkWindow *newFocus = NULL;
    int win_x, win_y;
    unsigned int buttonState = 0;
    Bool isTestingEvent = NO;
    Bool isMotionEvent = NO;
    Bool isOutside = NO;
    Bool firstDrag = NO;
    static int validPresses = 0, ignoredPresses = 0;
    static Bool ignoreDrags = NO;
    static Bool ignoreUpDown = NO;
    static NSTimeInterval timestamp = 0;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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 this event is not for a Tk toplevel, it should normally just be
     * passed up the responder chain.  However, there is are two exceptions.
     * One is for synthesized events, which are used in testing.  Those events
     * are recognized by having their timestamp set to 0.  The other is for
     * motion events sent by the local event monitor, which will have their
     * window attribute set to nil.
     */

    if (eventWindow && ![eventWindow isMemberOfClass:[TKWindow class]]) {
	if ([theEvent windowNumber] != -1 || [theEvent eventNumber] != -1)
	    return theEvent;
    }

    if (![eventWindow isMemberOfClass:[TKWindow class]]) {
	if ([theEvent timestamp] == 0) {
	    isTestingEvent = YES;
	    eventWindow = [NSApp keyWindow];
	}
	if (eventType == NSLeftMouseDragged ||
    /*
     * Check if the event is located in the titlebar.
	    eventType == NSMouseMoved) {
	    eventWindow = [NSApp keyWindow];
	    isMotionEvent = YES;
     */

    if (eventWindow) {
	}
	if (!isTestingEvent && !isMotionEvent) {
	    return theEvent;
	inTitleBar = viewFrame.size.height < location.y;
    }

	}
    } else if (!NSPointInRect(viewLocation, [contentView bounds])) {
	isOutside = YES;
    }
    button = [theEvent buttonNumber] + Button1;
    if ((button & -2) == Button2) {
	button ^= 1; /* Swap buttons 2/3 */
    }
    switch (eventType) {
    case NSRightMouseUp:
    case NSOtherMouseUp:
	buttonState &= ~Tk_GetButtonMask(button);
	buttonState &= ~TkGetButtonMask(button);
	break;
    case NSLeftMouseDragged:
	buttonState |= TkGetButtonMask(button);
	if (![NSApp tkDragTarget]) {
	    if (isOutside) {
		ignoreDrags = YES;
	    } else {
		firstDrag = YES;
	    }
	}
	if (ignoreDrags) {
	    return theEvent;
	}
	if (![NSApp tkDragTarget]) {
	    [NSApp setTkDragTarget: [NSApp tkEventTarget]];
	}
	break;
    case NSRightMouseDragged:
    case NSOtherMouseDragged:
	isMotionEvent = YES;
    case NSRightMouseDown:
    case NSOtherMouseDown:
	buttonState |= Tk_GetButtonMask(button);
	buttonState |= TkGetButtonMask(button);
	break;
    case NSMouseEntered:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	if (![eventWindow isKeyWindow] || isOutside) {
	    !inTitleBar) {
	    [(TKWindow *)eventWindow setMouseInResizeArea:YES];
	    return theEvent;
	}
	[NSApp setTkLiveResizeEnded:NO];
	[NSApp setTkPointerWindow:[NSApp tkEventTarget]];
	break;
    case NSMouseExited:
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)]) {
	    [(TKWindow *)eventWindow setMouseInResizeArea:NO];
	    break;
	if (![eventWindow isKeyWindow] || !isOutside) {
	    return theEvent;
	}
	[NSApp setTkPointerWindow:nil];
	break;
    case NSLeftMouseUp:
	[NSApp setTkDragTarget: nil];
	if ([theEvent clickCount] == 2) {
	    ignoreUpDown = NO;
	}
    case NSLeftMouseUp:
	if (ignoreUpDown) {
	    return theEvent;
	}
	if (ignoreDrags) {
	    ignoreDrags = NO;
	    return theEvent;
	}
	buttonState &= ~TkGetButtonMask(Button1);
	break;
    case NSLeftMouseDown:

	/*
	 * There are situations where Apple does not send NSLeftMouseUp events
	 * even though the mouse button has been released.  One of these is
	 * whenever a menu is posted on the screen.  This causes Tk to have an
	 * inaccurate idea of the current button state and to behave strangely.
	 * (See ticket[a132b5507e].)  As a work-around we watch for NSButtonDown
	 * events that arrive when Tk thinks the button is already down and
	 * we attempt to correct Tk's cached button state by insering a call to
	 * Tk_UpdatePointer showing the button as up.
	 */

	if ([NSApp tkButtonState] & TkGetButtonMask(Button1)) {
	    int fakeState = [NSApp tkButtonState] & ~TkGetButtonMask(Button1);
	    int x = location.x;
	    int y = floor(TkMacOSXZeroScreenHeight() - location.y);
	    Tk_UpdatePointer((Tk_Window) [NSApp tkEventTarget], x, y, fakeState);
	}

	/*
	 * Ignore left mouse button events which are in an NSWindow but outside
	 * of its contentView (see tickets [d72abe6b54] and [39cbacb9e8]).
	 * Ignore the first left button press after a live resize ends. (Apple
	 * sends the button press event that started the resize after the
	 * resize ends.  It should not be seen by Tk.  See tickets [d72abe6b54]
	 * and [39cbacb9e8]).  Ignore button press events when ignoreUpDown is
	 * set.  These are extraneous events which appear when double-clicking
	 * in a window without focus, causing duplicate Double-1 events (see
	 * ticket [7bda9882cb]).  When a LeftMouseDown event with clickCount 2
	 * is received we set the ignoreUpDown flag and we clear it when the
	 * matching LeftMouseUp with click count 2 is received.
	 */

	/*
	 * Make sure we don't ignore LeftMouseUp and LeftMouseDown forever.
	 * Currently tkBind.c sets NEARBY_MS to 500 (the Windows default).
	 */

	if ([theEvent timestamp] - timestamp > 1) {
	    ignoreUpDown = NO;
	}
	if ([theEvent clickCount] == 2) {
	    if (ignoreUpDown == YES) {
		return theEvent;
	    } else {
		timestamp = [theEvent timestamp];
		ignoreUpDown = YES;
	    }
	}
	if (!isTestingEvent) {
	    NSRect bounds = [contentView bounds];
	    NSRect grip = NSMakeRect(bounds.size.width - 10, 0, 10, 10);
	    bounds = NSInsetRect(bounds, 2.0, 2.0);
	    if (!NSPointInRect(viewLocation, bounds)) {
		return theEvent;
	    }
	    if (NSPointInRect(viewLocation, grip)) {
		return theEvent;
	    }
	    if ([NSApp tkLiveResizeEnded]) {
		[NSApp setTkLiveResizeEnded:NO];
		return theEvent;
	    }
	}

	/*
	 * If this click will change the focus, the Tk event should
	 * be sent to the toplevel which will be receiving focus rather than to
	 * the current focus window.  So reset tkEventTarget.
	 */

	if (eventWindow != [NSApp keyWindow]) {
	    NSWindow *w;

	    if (eventWindow && isOutside) {
		return theEvent;
	    }
	    for (w in [NSApp orderedWindows]) {
		if (NSPointInRect([NSEvent mouseLocation], [w frame])) {
		    newFocus = TkMacOSXGetTkWindow(w);
		    break;
		}
	    }
	    if (newFocus) {
		[NSApp setTkEventTarget: newFocus];
		[NSApp setTkPointerWindow: newFocus];
		target = (Tk_Window) newFocus;
	    }
	}
	buttonState |= TkGetButtonMask(Button1);
	break;
    case NSMouseMoved:
	if (eventWindow && eventWindow != [NSApp keyWindow]) {
	    return theEvent;
	}
	isMotionEvent = YES;
	break;
    case NSScrollWheel:

	/*
	 * Scroll wheel events are sent to the window containing the pointer,
	 * or ignored if no window contains the pointer.  See TIP #171.  Note,
	 * however, that TIP #171 proposed sending scroll wheel events to the
	 * focus window when no window contains the pointer.  That proposal was
	 * ultimately rejected.
	 */

	scrollTarget = TkMacOSXGetTkWindow(eventWindow);
#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
     * Find the toplevel window for the event.
     * resize or occur in the title bar.  See tickets [d72abe6b54] and
     * [39cbacb9e8].
     */

    if (eventType == NSLeftMouseDown) {
	if ([eventWindow respondsToSelector:@selector(mouseInResizeArea)] &&
	    [(TKWindow *) eventWindow mouseInResizeArea]) {

    if ([NSApp tkDragTarget]) {
	TkWindow *dragPtr = (TkWindow *) [NSApp tkDragTarget];
	TKWindow *dragWindow = nil;
	MacDrawable *topMacWin;
	    /*
	     * 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.
	     */

	if (dragPtr) {
	    buttonState &= ~Tk_GetButtonMask(Button1);
	    return theEvent;
	    dragWindow = (TKWindow *)TkMacOSXGetNSWindowForDrawable(
			    dragPtr->window);
	}
	if (inTitleBar) {
	if (!dragWindow) {
	    ignoredPresses++;
	    [NSApp setTkDragTarget: nil];
	    target = NULL;
	    return theEvent;
	}
	validPresses++;
	buttonState |= Tk_GetButtonMask(Button1);
    }
    if (eventType == NSLeftMouseUp) {
	if (ignoredPresses > 0) {
	    ignoredPresses--;
	} else if (validPresses > 0) {
	    validPresses--;
	}
	topMacWin = TkMacOSXGetHostToplevel(dragPtr);
	if (validPresses == 0) {
	if (topMacWin) {
	    buttonState &= ~Tk_GetButtonMask(Button1);
	}
    }

	    winPtr = topMacWin->winPtr;
    /*
     * Find an appropriate NSWindow to attach to this event, and its
     * associated Tk window.
     */

	}
    capture = TkpGetCapture();
    if (capture) {
	winPtr = (TkWindow *) capture;
    } else if (eventType == NSScrollWheel) {
	winPtr = scrollTarget;
	eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
	if (!eventWindow) {
	    return theEvent;
	}
    } else {
	if (eventWindow) {
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	}
	if (!winPtr) {
	    eventWindow = [NSApp mainWindow];
	winPtr = [NSApp tkEventTarget];
	    winPtr = TkMacOSXGetTkWindow(eventWindow);
	}
    }
    }
    if (!winPtr) {

	/*
	 * We couldn't find a Tk window for this event.  We have to ignore it.
	 * If we couldn't find a toplevel for this event we have to ignore it.
	 * (But this should never happen.)
	 */

#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)
     * Compute the mouse position in local (toplevel) 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);
    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;
    }

	    MacDrawable *topMacWin = TkMacOSXGetHostToplevel(winPtr);
	    if (topMacWin) {
		TkWindow* topPtr = topMacWin->winPtr;
		local.x -= (topPtr->wmInfoPtr->xInParent + contPtr->changes.x);
		local.y -= (topPtr->wmInfoPtr->yInParent + contPtr->changes.y);
	    }
	}
    }
    else {
    	if (winPtr && winPtr->wmInfoPtr) {
    	    local.x -= winPtr->wmInfoPtr->xInParent;
    	    local.y -= winPtr->wmInfoPtr->yInParent;
    	} else {
    	    return theEvent;
    	}
    }

    /*
     * 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.)
     * Use the toplevel coordinates to decide which Tk window should receive
     * this event.  Also convert the toplevel coordinates into the coordinate
     * system of that window.  These converted coordinates are needed for
     * XEvents that we generate, namely ScrollWheel events and Motion events
     * when the mouse is outside of the focused toplevel.
     */

    if ([NSApp tkDragTarget]) {
	Tk_Window dragTarget = (Tk_Window) [NSApp tkDragTarget];
	Tk_Window dragWidget = NULL;
	int x, y;
	Tk_GetRootCoords(dragTarget, &x, &y);
	win_x = global.x - x;
	win_y = global.y - y;
	if (firstDrag) {
	    dragWidget = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &x, &y);
	    if (dragWidget) {
		[NSApp setTkDragTarget: (TkWindow *) dragWidget];
	    }
	}
	target = (Tk_Window) [NSApp tkDragTarget];
    } else {
    target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
	target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
    }


    grabWinPtr = winPtr->dispPtr->grabWinPtr;

    /*
     * 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;
	Tk_Window w;
	if (!target) {
	    return theEvent;
	}
	for (tkwin2 = target;
	     !Tk_IsTopLevel(tkwin2);
	     tkwin2 = Tk_Parent(tkwin2)) {
	    if (tkwin2 == (Tk_Window)grabWinPtr) {
	for (w = target; !Tk_IsTopLevel(w); w = Tk_Parent(w)) {
	    if (w == (Tk_Window)grabWinPtr) {
		break;
	    }
	}
	if (w != (Tk_Window)grabWinPtr) {
	    return theEvent;
	}
    }

    /*
     * Ignore the event if a global grab is in effect and the Tk window is
     * not in the grabber's subtree.
     */

    if (grabWinPtr && /* There is a grab in effect ... */
	winPtr->dispPtr->grabFlags && /* and it is a global grab ... */
	grabWinPtr->mainPtr == winPtr->mainPtr) { /* in the same application. */
	Tk_Window w;
	if (!target) {
	    return theEvent;
	}
	for (w = target; !Tk_IsTopLevel(w); w = Tk_Parent(w)) {
	    if (w == (Tk_Window)grabWinPtr) {
		break;
	    }
	}
	if (tkwin2 != (Tk_Window)grabWinPtr) {
	    return theEvent;
	if (w != (Tk_Window)grabWinPtr) {
	    /* Force the focus back to the grab window. */
	    TkpChangeFocus(grabWinPtr, 1);
	}
    }

    /*
     *  Generate an XEvent for this mouse event.
     *  Translate the current button state into Tk's format.
     */

    unsigned int state = buttonState;
    NSUInteger modifiers = [theEvent modifierFlags];

    if (modifiers & NSAlphaShiftKeyMask) {
	state |= LockMask;
    }
    if (modifiers & NSShiftKeyMask) {
	state |= ShiftMask;
    }
    if (modifiers & NSControlKeyMask) {
287
288
289
290
291
292
293

294






295

296
297
298



299
300
301



302
303
304
305
306






























307








308


309
310

311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327


328
329

330
331
332
333

334


335
336

337
338




















339
340
341
342
343
344
345
475
476
477
478
479
480
481
482
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







+

+
+
+
+
+
+

+

-
-
+
+
+
-
-
-
+
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
-
+
+


+
-
+
-
-
-
-










-
+

+
+

-
+



-
+

+
+

-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    }
    if (modifiers & NSNumericPadKeyMask) {
	state |= Mod3Mask;
    }
    if (modifiers & NSFunctionKeyMask) {
	state |= Mod4Mask;
    }
    [NSApp setTkButtonState:state];

    /*
     * Send XEvents.  We do this here for Motion events outside of the focused
     * toplevel and for MouseWheel events.  In other cases the XEvents will be
     * sent when we call Tk_UpdatePointer.
     */

    if (eventType != NSScrollWheel) {
	if ([NSApp tkDragTarget]) {

	/*
	 * For normal mouse events, Tk_UpdatePointer will send the appropriate
	    /*
	     * When dragging the mouse into the resize area Apple shows the
	     * left button to be up, which confuses Tk_UpdatePointer.  So
	 * XEvents using its cached state information.  Unfortunately, it will
	 * also recompute the local coordinates.
	 */
	     * we make sure that the button state appears the way that Tk
	     * expects.
	     */

#ifdef TK_MAC_DEBUG_EVENTS
	TKLog(@"UpdatePointer %p x %.1f y %.1f %d",
		target, global.x, global.y, state);
#endif
	    state |= TkGetButtonMask(Button1);
	}
	if (eventType == NSMouseEntered) {
	    Tk_UpdatePointer((Tk_Window) [NSApp tkPointerWindow],
				 global.x, global.y, state);
	} else if (eventType == NSMouseExited) {
	    if ([NSApp tkDragTarget]) {
	    	Tk_UpdatePointer((Tk_Window) [NSApp tkDragTarget],
	    			 global.x, global.y, state);
	    } else {
	    Tk_UpdatePointer(NULL, global.x, global.y, state);
	    }
	} else if (eventType == NSMouseMoved ||
		   eventType == NSLeftMouseDragged) {
	    if ([NSApp tkPointerWindow]) {
		Tk_UpdatePointer(target, global.x, global.y, state);
	    } else {
		XEvent xEvent = {0};

		xEvent.type = MotionNotify;
		xEvent.xany.send_event = false;
		xEvent.xany.display = Tk_Display(target);
		xEvent.xany.window = Tk_WindowId(target);
		xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
		xEvent.xmotion.x = win_x;
		xEvent.xmotion.y = win_y;
		xEvent.xmotion.x_root = global.x;
		xEvent.xmotion.y_root = global.y;
		xEvent.xmotion.state = state;
		Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);

		/*
		 * Tk_UpdatePointer must not be called in this case.  Doing so
		 * will break scrollbars; dragging will stop when the mouse
		 * leaves the window.
		 */

	    }
	} else {
	Tk_UpdatePointer(target, global.x, global.y, state);
	    Tk_UpdatePointer(target, global.x, global.y, state);
	}
    } else {
	CGFloat delta;
	int coarseDelta;
	XEvent xEvent;
	XEvent xEvent = {0};

	/*
	 * 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;
	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 = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
	delta = [theEvent deltaX] * 120;
	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 = (delta > 0) ? ceil(delta) : floor(delta);
	    xEvent.xkey.keycode = coarseDelta;
	    xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
	    Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
	}
    }

    /*
     * If button events are being captured, and the target is not in the
     * subtree below the capturing window, then the NSEvent should not be sent
     * up the responder chain.  This avoids, for example, beeps when clicking
     * the mouse button outside of a posted combobox.  See ticket [eb26d4ec8e].
     */

    capture = TkMacOSXGetCapture();
    if (capture && eventType == NSLeftMouseDown) {
	Tk_Window w;
	for (w = target; w != NULL;  w = Tk_Parent(w)) {
	    if (w == capture) {
		break;
	    }
	}
	if (w != capture) {
	    return nil;
	}
    }
    return theEvent;
}
@end

#pragma mark -
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
613
614
615
616
617
618
619









































































620
621
622
623
624
625
626
627







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







 *
 *----------------------------------------------------------------------
 */

unsigned int
TkMacOSXButtonKeyState(void)
{
    UInt32 buttonState = 0, keyModifiers;
    int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront());

    buttonState = isFrontProcess ? GetCurrentEventButtonState() :
	    GetCurrentButtonState();
    keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() :
	    GetCurrentKeyModifiers();

    return ButtonModifiers2State(buttonState, keyModifiers);
}

/*
 *----------------------------------------------------------------------
 *
 * ButtonModifiers2State --
 *
 *	Converts Carbon mouse button state and modifier values into a Tk
 *	button/modifier state.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static unsigned int
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;
    }
    if (keyModifiers & controlKey) {
	state |= ControlMask;
    }
    if (keyModifiers & cmdKey) {
	state |= Mod1Mask;		/* command key */
    }
    if (keyModifiers & optionKey) {
	state |= Mod2Mask;		/* option key */
    }
    if (keyModifiers & kEventKeyModifierNumLockMask) {
	state |= Mod3Mask;
    }
    if (keyModifiers & kEventKeyModifierFnMask) {
	state |= Mod4Mask;
    }

    return state;
    return [NSApp tkButtonState];
}

/*
 *----------------------------------------------------------------------
 *
 * XQueryPointer --
 *
456
457
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
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







-
+

-
-
+
+








-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

Bool
XQueryPointer(
    Display *display,
    TCL_UNUSED(Display *),
    Window w,
    Window *root_return,
    Window *child_return,
    TCL_UNUSED(Window *),
    TCL_UNUSED(Window *),
    int *root_x_return,
    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);
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
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







-
+











-







     * 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)) {
	    && 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;
}

/*
 *----------------------------------------------------------------------
 *
682
683
684
685
686
687
688






689
690
691
692
693
694
695
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878







+
+
+
+
+
+







	pt.y = y + dispPtr->warpY;
    } else {
	pt.x = dispPtr->warpX;
	pt.y = dispPtr->warpY;
    }

    CGWarpMouseCursorPosition(pt);

    if (dispPtr->warpWindow) {
        TkGenerateButtonEventForXPointer(Tk_WindowId(dispPtr->warpWindow));
    } else {
        TkGenerateButtonEventForXPointer(None);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCapture --
 *
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
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







-
+











-
+












    }
    captureWinPtr = (Tk_Window)winPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpGetCapture --
 * TkMacOSXGetCapture --
 *
 * Results:
 *	Returns the current grab window
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tk_Window
TkpGetCapture(void)
TkMacOSXGetCapture(void)
{
    return captureWinPtr;
}

/*
 * 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
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15

16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60






-
-
-
-
+
+
+
+





-

-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








-
+







/*
 * 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.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 "tkMacOSXEvent.h"
#include "tkMacOSXConstants.h"

#ifdef USE_TCL_STUBS
#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 {
    int magic;
    void *hooks;
    void (*dummy[19]) (void); /* dummy entries 0-18, not used */
    void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */
} TclIntPlatStubs;
extern const TclIntPlatStubs *tclIntPlatStubsPtr;
#ifdef __cplusplus
}
#endif
#define TclMacOSXNotifierAddRunLoopMode \
	(tclIntPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode) /* 19 */
#elif TCL_MINOR_VERSION < 7
    extern void TclMacOSXNotifierAddRunLoopMode(const void *runLoopMode);
#else
    extern void Tcl_MacOSXNotifierAddRunLoopMode(const void *runLoopMode);
#   define TclMacOSXNotifierAddRunLoopMode Tcl_MacOSXNotifierAddRunLoopMode
#endif
#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 = \
#define TSD_INIT() ThreadSpecificData *tsdPtr = (ThreadSpecificData *) \
	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
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191







-
+







     * 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 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:
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356

357
358
359
360
361
362
363
315
316
317
318
319
320
321

322
323

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342


343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389







-
+

-



















-
-
+
+
+
















-
+


















+
-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TkMacOSXNotifyExitHandler(
    ClientData dummy)	/* Not used. */
    ClientData clientData)	/* 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.
 *       only times when any NSViews have the needsDisplay property set to YES
 *       are during execution of this function or in the addTkDirtyRect method
 *       of TKContentView.
 *
 *       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.
 *	Parts of windows may 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 layer] setNeedsDisplayInRect:[view tkDirtyRect]];
		[view setNeedsDisplayInRect:[view tkDirtyRect]];
		[view setNeedsDisplay:YES];
	    }
	} else {
	    [window displayIfNeeded];
	}
    }
    if (dirtyCount) {
    	*dirtyCount = count;
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
434
435
436
437
438
439
440

441
442
443
444
445
446
447
448
449
450
451
452

453
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







-
+











-
+



-
















-
+







 */

#define TICK 200
static Tcl_TimerToken ticker = NULL;

static void
Heartbeat(
    TCL_UNUSED(ClientData))
    ClientData clientData)
{

    if (ticker) {
	ticker = Tcl_CreateTimerHandler(TICK, Heartbeat, NULL);
    }
}

static const Tcl_Time zeroBlockTime = { 0, 0 };

static void
TkMacOSXEventsSetupProc(
    ClientData dummy,
    ClientData clientData,
    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.
	 * time to 0 and stop the heartbeat.
  	 */

	NSEvent *currentEvent =
	        [NSApp nextEventMatchingMask:NSAnyEventMask
			untilDate:[NSDate distantPast]
			inMode:GetRunLoopMode(TkMacOSXGetModalSession())
			dequeue:NO];
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
512
513
514
515
516
517
518

519
520
521
522

523
524
525
526
527
528
529







-
+



-







 *	NSevents are used to generate X events, which are added to the Tcl
 *      event queue.
 *
 *----------------------------------------------------------------------
 */
static void
TkMacOSXEventsCheckProc(
    TCL_UNUSED(ClientData),
    ClientData 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;
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
561
562
563
564
565
566
567

568
569
570
571
572
573
574







-








		/*
		 * 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];
Changes to macosx/tkMacOSXPort.h.
1
2
3
4
5
6
7
8
9
10



11
12
13
14
15
16
17
1
2
3
4
5
6
7



8
9
10
11
12
13
14
15
16
17







-
-
-
+
+
+







/*
 * 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>
 * Copyright © 1994-1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45


46
47
48

49
50
51
52
53
54
55
31
32
33
34
35
36
37





38
39


40
41



42
43
44
45
46
47
48
49







-
-
-
-
-
+

-
-
+
+
-
-
-
+







#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
#ifdef HAVE_SYS_TIME_H
#	include <sys/time.h>
#   else
#	include <time.h>
#endif
#include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#ifdef 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>
73
74
75
76
77
78
79













80
81
82
83
84
85
86
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93







+
+
+
+
+
+
+
+
+
+
+
+
+







#   if defined(_IBMR2)
#	define SELECT_MASK void
#   else
#	define SELECT_MASK int
#   endif
#endif

/*
 * Used to tag functions that are only to be visible within the module being
 * built and not outside it (where this is supported by the linker).
 */

#ifndef MODULE_SCOPE
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#	define MODULE_SCOPE extern
#   endif
#endif

/*
 * The following macro defines the number of fd_masks in an fd_set:
 */

#ifndef FD_SETSIZE
#   ifdef OPEN_MAX
#	define FD_SETSIZE OPEN_MAX
106
107
108
109
110
111
112




















113
114
115
116
117
118
119
120
121











122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139


140
141
142






143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175


176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194








195
196
197
198
199
200
201
202
203







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









+
+
+
+
+
+
+
+
+
+
+





-
+










-
-
+
+


-
+
+
+
+
+
+









-
-
-
-
-
-
-
-










/*
 * 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.
 */

#undef XFlush
#define XFlush(display) (0)
#undef XFree
#define XFree(data) (((data) != NULL) ? (ckfree(data),0) : 0)
#undef XGrabServer
#define XGrabServer(display) (0)
#undef XNoOp
#define XNoOp(display) (LastKnownRequestProcessed(display)++,0)
#undef XUngrabServer
#define XUngrabServer(display) (0)
#undef XSynchronize
#define XSynchronize(display, onoff) (LastKnownRequestProcessed(display)++,NULL)
#undef XVisualIDFromVisual
#define XVisualIDFromVisual(visual) (visual->visualid)

/*
 * 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)

/*
 * TkMacOSXGetCapture is a legacy function used on the Mac. When fixing
 * [943d5ebe51], TkpGetCapture was added to the Windows port. Both
 * are actually the same feature and should bear the same name. However,
 * in order to avoid potential backwards incompatibilities, renaming
 * TkMacOSXGetCapture into TkpGetCapture in *PlatDecls.h shall not be
 * done in a patch release, therefore use a define here.
 */

#define TkpGetCapture TkMacOSXGetCapture

/*
 * This macro stores a representation of the window handle in a string.
 */

#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "0x%lx", (unsigned long) (w))
	snprintf((buf), TCL_INTEGER_SPACE, "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.
 * Inform tkImgPhInstance.c that we implement TkpPutRGBAImage to render RGBA
 * images directly into a window.
 */

#define TKPUTIMAGE_CAN_BLEND
#define TK_CAN_RENDER_RGBA

MODULE_SCOPE int TkpPutRGBAImage(
		     Display* display, Drawable drawable, GC gc,XImage* image,
		     int src_x, int src_y, int dest_x, int dest_y,
		     unsigned int width, unsigned int height);

/*
 * 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 */
Changes to macosx/tkMacOSXPrivate.h.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * 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
 * Copyright © 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2008-2009 Apple Inc.
 * Copyright © 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$
 */

23
24
25
26
27
28
29




30
31
32
33
34
35
36
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40







+
+
+
+







#ifndef __clang__
#define instancetype id
#endif

#define TextStyle MacTextStyle
#import <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#endif
#ifndef NO_CARBON_H
#import <Carbon/Carbon.h>
#endif
#undef TextStyle
#import <objc/runtime.h> /* for sel_isEqual() */

#ifndef _TKMACINT
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150







-
+







 *  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. */
    unsigned virt: 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
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172







-
+







} 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 ON_KEYPAD(virt) ((virt >= 0x41) && (virt <= 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.
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221


222
223
224
225
226
227
228
229
230
231
232
233

234
235

236
237
238
239
240
241
242
204
205
206
207
208
209
210

211
212






213
214
215
216


217
218
219






220
221



222


223
224
225
226
227
228
229
230







-


-
-
-
-
-
-




-
-
+
+

-
-
-
-
-
-


-
-
-
+
-
-
+







 * 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,
MODULE_SCOPE HIShapeRef	TkMacOSXGetNativeRegion(TkRegion r);
MODULE_SCOPE void	TkMacOSXSetWithNativeRegion(TkRegion 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,
MODULE_SCOPE int	TkMacOSXCountRectsInRegion(HIShapeRef shape);
			    HIShapeRef inShape2, HIMutableShapeRef outResult);

MODULE_SCOPE void       TkMacOSXPrintRectsInRegion(HIShapeRef shape);
/*
 * Prototypes of TkAqua internal procs.
 */

MODULE_SCOPE void *	TkMacOSXGetNamedSymbol(const char *module,
			    const char *symbol);
MODULE_SCOPE void	TkMacOSXDisplayChanged(Display *display);
254
255
256
257
258
259
260
261
262


263
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284

285
286
287
288
289
290

291
292
293
294
295
296

297


298
299
300
301
302
303
304
242
243
244
245
246
247
248


249
250
251

252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267

268



269


270
271
272

273

274
275
276
277

278
279
280
281
282
283
284
285
286
287
288







-
-
+
+

-
+








-







-
+
-
-
-
+
-
-



-
+
-




-
+

+
+







			    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 TkMacOSXGetTkWindow(window) ((TkWindow *)Tk_MacOSXGetTkWindow(window))
#define TkMacOSXGetNSWindowForDrawable(drawable) ((NSWindow *)TkMacOSXDrawable(drawable))
#define TkMacOSXGetNSViewForDrawable(macWin) ((NSView *)Tk_MacOSXGetNSViewForDrawable((Drawable)(macWin)))
#define TkMacOSXGetCGContextForDrawable(drawable) ((CGContextRef)Tk_MacOSXGetCGContextForDrawable(drawable))
MODULE_SCOPE CGContextRef TkMacOSXGetCGContextForDrawable(Drawable 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,
MODULE_SCOPE Tcl_ObjCmdProc TkMacOSXStandardAboutPanelObjCmd;
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkMacOSXIconBitmapObjCmd(ClientData clientData,
MODULE_SCOPE Tcl_ObjCmdProc TkMacOSXIconBitmapObjCmd;
			    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,
MODULE_SCOPE Tcl_ObjCmdProc TkMacOSXRegisterServiceWidgetObjCmd;
			    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 void	TkMacOSXDrawAllViews(void *clientData);
MODULE_SCOPE unsigned long TkMacOSXClearPixel(void);
MODULE_SCOPE NSString*  TkMacOSXOSTypeToUTI(OSType ostype);
MODULE_SCOPE NSImage*   TkMacOSXIconForFileType(NSString *filetype);

#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))

enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu};

329
330
331
332
333
334
335





336
337
338
339
340
341
342










343
344
345
346
347
348
349
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348







+
+
+
+
+







+
+
+
+
+
+
+
+
+
+








#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;
    int _macOSVersion;  /* 10000 * major + 100*minor */
    Bool _isDrawing;
    Bool _needsToDraw;
    Bool _tkLiveResizeEnded;
    TkWindow *_tkPointerWindow;
    TkWindow *_tkEventTarget;
    TkWindow *_tkDragTarget;
    unsigned int _tkButtonState;
#endif

}
@property int poolLock;
@property int macOSVersion;
@property Bool isDrawing;
@property Bool needsToDraw;
@property Bool tkLiveResizeEnded;

/*
 * Persistent state variables used by processMouseEvent.
 */

@property(nonatomic) TkWindow *tkPointerWindow;
@property(nonatomic) TkWindow *tkEventTarget;
@property(nonatomic) TkWindow *tkDragTarget;
@property unsigned int tkButtonState;

@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
410
411
412
413
414
415
416

417
418
419
420
421
422
423
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423







+








@interface TKContentView : NSView <NSTextInputClient>
{
@private
    NSString *privateWorkingText;
    Bool _tkNeedsDisplay;
    NSRect _tkDirtyRect;
    NSTrackingArea *trackingArea;
}
@property Bool tkNeedsDisplay;
@property NSRect tkDirtyRect;
@end

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
437
438
439
440
441
442
443

444
445
446

447
448
449
450
451
452
453







-



-







@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

555
556
557
558
559
560
561

562
563
564
565
566
567
568
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567







+







 *---------------------------------------------------------------------------
 */

@interface TKNSString:NSString {
@private
    Tcl_DString _ds;
    NSString *_string;
    const char *_UTF8String;
}
@property const char *UTF8String;
@property (readonly) Tcl_DString DString;
- (instancetype)initWithTclUtfBytes:(const void *)bytes
			     length:(NSUInteger)len;
@end

Changes to macosx/tkMacOSXRegion.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
1
2
3
4
5



6
7
8
9
10
11
12
13
14

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

29
30

31
32
33
34
35
36
37
38
39
40
41
42


43
44
45



46
47
48
49
50
51
52
53
54

55
56

57
58
59
60
61
62
63
64
65
66
67
68
69


70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97




98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125




126
127
128
129
130
131
132
133
134
135
136
137
138

139
140

141
142
143
144
145
146
147
148
149
150
151
152
153

154
155


156
157
158
159
160
161
162

163
164
165
166
167

168
169
170
171
172
173
174
175





-
-
-
+
+
+






-














-
+

-
+











-
-
+
+

-
-
-
+
+
+






-
+

-
+












-
-
+
+











-
+














-
-
-
-
+
+
+
+









-
+














-
-
-
-
+
+
+
+









-
+

-
+












-
+

-
-
+
+





-
+




-
+







/*
 * tkMacOSXRegion.c --
 *
 *	Implements X window calls for manipulating regions
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 --
 * TkCreateRegion --
 *
 *	Implements the equivelent of the X window function XCreateRegion. See
 *	Implements the equivalent of the X window function XCreateRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	Returns an allocated region handle.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Region
XCreateRegion(void)
TkRegion
TkCreateRegion(void)
{
    Region region = (Region) HIShapeCreateMutable();
    DebugLog("Created region: total regions = %d\n", ++totalRegions);
    RetainRegion(region);
    TkRegion region = (TkRegion) HIShapeCreateMutable();
    DebugLog("Created region: total regions = %d, total count is %d\n",
	++totalRegions, ++totalRegionRetainCount);
    return region;
}

/*
 *----------------------------------------------------------------------
 *
 * XDestroyRegion --
 * TkDestroyRegion --
 *
 *	Implements the equivelent of the X window function XDestroyRegion. See
 *	Implements the equivalent of the X window function XDestroyRegion. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Memory is freed.
 *
 *----------------------------------------------------------------------
 */

int
XDestroyRegion(
    Region r)
TkDestroyRegion(
    TkRegion r)
{
    if (r) {
	DebugLog("Destroyed region: total regions = %d\n", --totalRegions);
	ReleaseRegion(r);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XIntersectRegion --
 * TkIntersectRegion --
 *
 *	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)
TkIntersectRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb,
	   (HIMutableShapeRef) dr_return);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XSubtractRegion --
 * TkSubtractRegion --
 *
 *	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)
TkSubtractRegion(
    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb,
	   (HIMutableShapeRef) dr_return);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XUnionRectWithRegion --
 * TkUnionRectWithRegion --
 *
 *	Implements the equivelent of the X window function
 *	Implements the equivalent of the X window function
 *	XUnionRectWithRegion. See Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XUnionRectWithRegion(
TkUnionRectWithRegion(
    XRectangle* rectangle,
    Region src_region,
    Region dest_region_return)
    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,
	ChkErr(HIShapeUnionWithRect,
		(HIMutableShapeRef) dest_region_return, &r);
    } else {
	HIShapeRef rectRgn = HIShapeCreateWithRect(&r);

	ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region,
	ChkErr(HIShapeUnion, rectRgn, (HIShapeRef) src_region,
		(HIMutableShapeRef) dest_region_return);
	CFRelease(rectRgn);
    }
    return Success;
}

/*
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202

203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

239
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254


255
256
257
258
259
260
261
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200

201
202

203
204
205
206
207
208
209
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238

239
240
241
242
243
244
245
246
247
248
249
250
251


252
253
254
255
256
257
258
259
260







-
+







-
+

-
+













-
-
+
+


















-
+

-
+












-
-
+
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TkMacOSXIsEmptyRegion(
    Region r)
    TkRegion r)
{
    return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0;
}

/*
 *----------------------------------------------------------------------
 *
 * XRectInRegion --
 * TkRectInRegion --
 *
 *	Implements the equivelent of the X window function XRectInRegion. See
 *	Implements the equivalent 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,
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;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * XClipBox --
 * TkClipBox --
 *
 *	Implements the equivelent of the X window function XClipBox. See
 *	Implements the equivalent of the X window function XClipBox. See
 *	Xwindow documentation for more details.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XClipBox(
    Region r,
TkClipBox(
    TkRegion r,
    XRectangle *rect_return)
{
    CGRect rect;

    HIShapeGetBounds((HIShapeRef) r, &rect);
    rect_return->x = rect.origin.x;
    rect_return->y = rect.origin.y;
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
278
279
280
281
282
283
284

285
286
287
288
289
290
291
292







-
+







 *	The region is updated, with extra pixels added to it.
 *
 *----------------------------------------------------------------------
 */

void
TkpBuildRegionFromAlphaData(
    Region region,			/* Region to update. */
    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
319
320
321
322
323
324
325

326
327
328
329
330
331
























332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358







-
+





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



















-
+







		lineDataPtr += pixelStride;
	    }
	    if (end > x1) {
		rect.x = x + x1;
		rect.y = y + y1;
		rect.width = end - x1;
		rect.height = 1;
		XUnionRectWithRegion(&rect, region, region);
		TkUnionRectWithRegion(&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)
    TkRegion r)
{
    CFRelease(r);
    DebugLog("Released region: total count is %d\n", --totalRegionRetainCount);
}

/*
 *----------------------------------------------------------------------
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382







-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetEmptyRegion(
    Region r)
    TkRegion r)
{
    ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r);
}

/*
 *----------------------------------------------------------------------
 *
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405







-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXGetNativeRegion(
    Region r)
    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
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
414
415
416
417
418
419
420

421
422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
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







-
+


-
+




















-
+










+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-













-
-
-
-
-
+
+
+
+
+
+
+

+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-

+
+
+
-
-
+
+
-
-

-
+








 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkMacOSXSetWithNativeRegion(
    Region r,
    TkRegion r,
    HIShapeRef rgn)
{
    ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
    ChkErr(HIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
}

/*
 *----------------------------------------------------------------------
 *
 * XOffsetRegion --
 *
 *	Offsets region by given distances.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XOffsetRegion(
    Region r,
    void *r,
    int dx,
    int dy)
{
    ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCopyRegion --
 *
 *  Makes the destination region a copy of the source region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
 * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
 * TkMacOSXHIShapeSetWithShape,
 * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
 * TkMacOSHIShapeUnion --

void
TkpCopyRegion(
    TkRegion dst,
    TkRegion src)
{
    ChkErr(HIShapeSetWithShape, (HIMutableShapeRef)dst, (HIShapeRef)src);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSHIShapeDifferenceWithRect --
 *
 *	Wrapper functions for missing/buggy HIShape API
 *
 *----------------------------------------------------------------------
 */

HIShapeRef
TkMacOSXHIShapeCreateEmpty(void)
{
    HIShapeRef result;

    result = HIShapeCreateEmpty();
    return result;
}

HIMutableShapeRef
TkMacOSXHIShapeCreateMutableWithRect(
    const CGRect *inRect)
{
    HIMutableShapeRef result;

    result = HIShapeCreateMutableWithRect(inRect);
    return result;
}

OSStatus
TkMacOSXHIShapeSetWithShape(
    HIMutableShapeRef inDestShape,
    HIShapeRef inSrcShape)
{
    OSStatus result;

    result = HIShapeSetWithShape(inDestShape, inSrcShape);
    return result;
}

OSStatus
TkMacOSHIShapeDifferenceWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)
{
    OSStatus result;
    HIShapeRef rgn = HIShapeCreateWithRect(inRect);

    result = HIShapeDifference(inShape, rgn, inShape);
    CFRelease(rgn);

    return result;
}

OSStatus
TkMacOSHIShapeUnionWithRect(
    HIMutableShapeRef inShape,
    const CGRect *inRect)

static OSStatus
rectCounter(
    int msg,
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    void *ref)
{
    int *count = (int *)ref;
    (*count)++;
    return noErr;
}

    OSStatus result;

    result = HIShapeUnionWithRect(inShape, inRect);
    return result;
static OSStatus
rectPrinter(
    int msg,
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    void *ref)
{
    if (rect) {
	fprintf(stderr, "    %s\n", NSStringFromRect(*rect).UTF8String);
    }
    return noErr;
}

OSStatus
TkMacOSHIShapeUnion(
    HIShapeRef inShape1,
    HIShapeRef inShape2,
int
TkMacOSXCountRectsInRegion(
    HIShapeRef shape)
{
    int rect_count = 0;
    if (!HIShapeIsEmpty(shape)) {
	ChkErr(HIShapeEnumerate, shape,
		kHIShapeParseFromBottom|kHIShapeParseFromLeft,
		rectCounter, &rect_count);
    }
    return rect_count;
}

void
TkMacOSXPrintRectsInRegion(
    HIShapeRef shape)
    HIMutableShapeRef outResult)
{
    if (!HIShapeIsEmpty(shape)) {
	ChkErr(HIShapeEnumerate, shape,
		kHIShapeParseFromBottom|kHIShapeParseFromLeft,
    OSStatus result;

		rectPrinter, NULL);
    }
    result = HIShapeUnion(inShape1, inShape2, outResult);
    return result;
}


/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
Changes to macosx/tkMacOSXScale.c.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17






-
-
-
-
+
+
+
+







/*
 * tkMacOSXScale.c --
 *
 *	This file implements the Macintosh specific portion of the
 *	scale widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2008-2009, Apple Inc.
 * Copyright © 1996 Sun Microsystems, Inc.
 * Copyright © 1998-2000 Scriptics Corporation.
 * Copyright © 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 "tkScale.h"
386
387
388
389
390
391
392
393
394
395



396
397
398

399
400
401
402
403
404
405
386
387
388
389
390
391
392



393
394
395



396
397
398
399
400
401
402
403







-
-
-
+
+
+
-
-
-
+







    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
    TkMacOSXWinBounds((TkWindow *) macScalePtr->info.tkwin, &bounds);
    where.h = eventPtr->xbutton.x + bounds.left;
    where.v = eventPtr->xbutton.y + bounds.top;
     * control was hit and act accordingly.
     */

#ifdef TK_MAC_DEBUG_SCALE
    TkMacOSXDbgMsg("calling TestControl");
#endif
    part = TestControl(macScalePtr->scaleHandle, where);
    if (part == 0) {
	return;
    }

Changes to macosx/tkMacOSXScrlbr.c.
1
2
3
4
5
6
7
8
9
10
11





12
13
14
15
16
17
18
1
2
3
4
5
6





7
8
9
10
11
12
13
14
15
16
17
18






-
-
-
-
-
+
+
+
+
+







/*
 * 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
 * Copyright © 1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2015 Kevin Walzer/WordTech Commununications LLC.
 * Copyright © 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"
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256







-
+







}
#endif

void
TkpDisplayScrollbar(
    ClientData clientData)	/* Information about window. */
{
    TkScrollbar *scrollPtr = clientData;
    TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;

452
453
454
455
456
457
458
459

460
461
462

463
464
465
466
467
468
469
452
453
454
455
456
457
458

459
460
461

462
463
464
465
466
467
468
469







-
+


-
+








void
TkpDestroyScrollbar(
    TkScrollbar *scrollPtr)
{
    MacScrollbar *macScrollPtr = (MacScrollbar *) scrollPtr;

    if (macScrollPtr->troughGC != None) {
    if (macScrollPtr->troughGC != NULL) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
    if (macScrollPtr->copyGC != NULL) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+













-







    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;
    short 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.
     */

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
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







-
+













-
+


-
+











 */

static void
ScrollbarEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkScrollbar *scrollPtr = clientData;
    TkScrollbar *scrollPtr = (TkScrollbar *)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);
    	ScrollbarEvent(scrollPtr, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
	TkScrollbarEventProc(scrollPtr, eventPtr);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
Changes to macosx/tkMacOSXSend.c.
18
19
20
21
22
23
24
25
26
27
28




29
30
31
32
33
34
35
18
19
20
21
22
23
24




25
26
27
28
29
30
31
32
33
34
35







-
-
-
-
+
+
+
+







 *	interps in one wish app, and you need to send it to the right one.
 *
 *	Implementing this has been on our list of things to do, but what with
 *	the demise of Tcl at Sun, and the lack of resources at Scriptics it
 *	may not get done for awhile. So this sketch is offered for the brave
 *	to attempt if they need the functionality...
 *
 * Copyright (c) 1989-1994 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1989-1994 The Regents of the University of California.
 * Copyright © 1994-1998 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 "tkMacOSXInt.h"

205
206
207
208
209
210
211
212


213
214
215
216
217
218
219
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220







-
+
+







				 * 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. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Tcl_Interp *interp = winPtr->mainPtr->interp;
    int i, suffix, offset, result;
    int suffix, result;
    int i, offset;
    RegisteredInterp *riPtr, *prevPtr;
    const char *actualName;
    Tcl_DString dString;
    Tcl_Obj *resultObjPtr, *interpNamePtr;
    char *interpName;

    if (!initialized) {
259
260
261
262
263
264
265
266

267
268
269
270

271
272
273
274
275
276
277
260
261
262
263
264
265
266

267
268
269
270

271
272
273
274
275
276
277
278







-
+



-
+







	}
	interpName = Tcl_GetString(interpNamePtr);
	if (strcmp(actualName, interpName) == 0) {
	    if (suffix == 1) {
		Tcl_DStringAppend(&dString, name, -1);
		Tcl_DStringAppend(&dString, " #", 2);
		offset = Tcl_DStringLength(&dString);
		Tcl_DStringSetLength(&dString, offset + 10);
		Tcl_DStringSetLength(&dString, offset + TCL_INTEGER_SPACE);
		actualName = Tcl_DStringValue(&dString);
	    }
	    suffix++;
	    sprintf(Tcl_DStringValue(&dString) + offset, "%d", suffix);
	    snprintf(Tcl_DStringValue(&dString) + offset, TCL_INTEGER_SPACE, "%d", suffix);
	    i = 0;
	} else {
	    i++;
	}
    }

    Tcl_DecrRefCount(resultObjPtr);
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342







-
+











-







 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SendObjCmd(
    ClientData dummy,	/* Not used */
    TCL_UNUSED(void *),
    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;
458
459
460
461
462
463
464
465

466
467
468
469
470
471
472
473
474
475
476
477
458
459
460
461
462
463
464

465
466
467
468
469

470
471
472
473
474
475
476







-
+




-







 *
 *----------------------------------------------------------------------
 */

int
TkGetInterpNames(
    Tcl_Interp *interp,		/* Interpreter for returning a result. */
    Tk_Window tkwin)		/* Window whose display is to be used for the
    TCL_UNUSED(Tk_Window))		/* 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;
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511
512
513
514
515
516
495
496
497
498
499
500
501

502
503

504
505
506
507
508
509
510
511
512
513
514







-
+

-











 *	Sets up various data structures and windows.
 *
 *--------------------------------------------------------------
 */

static int
SendInit(
    Tcl_Interp *dummy)		/* Not used */
    TCL_UNUSED(Tcl_Interp *))
{
    (void)dummy;
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
Changes to macosx/tkMacOSXServices.c.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * 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.
 * Copyright © 2010-2019 Kevin Walzer/WordTech Communications LLC.
 * Copyright © 2019 Marc Culler.
 * Copyright © 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>
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
130
131
132
133
134
135
136

137
138
139
140
141
142
143







-







	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 *))
Changes to macosx/tkMacOSXSubwindows.c.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







/*
 * tkMacOSXSubwindows.c --
 *
 *	Implements subwindows for the macintosh version of Tk.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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 "tkMacOSXDebug.h"
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
138







+
















+


-
+




















-
+







	    CFRelease(macWin->drawRgn);
            macWin->drawRgn = NULL;
	}

	if (macWin->toplevel->referenceCount == 0) {
	    ckfree(macWin->toplevel);
	}
	macWin->winPtr->privatePtr = NULL;
	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;
    macWin->winPtr->privatePtr = NULL;

    /*
     * Delay deletion of a toplevel data structure untill all children have
     * Delay deletion of a toplevel data structure until 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.
 *	Always returns Success or BadWindow.
 *
 * Side effects:
 *	The subwindow or toplevel may appear on the screen.  VisibilityNotify
 *      events are generated.
 *
 *
 *----------------------------------------------------------------------
144
145
146
147
148
149
150


151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
146
147
148
149
150
151
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 (!window) {
	return BadWindow;
    }
    MacDrawable *macWin = (MacDrawable *)window;
    TkWindow *winPtr = macWin->winPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);
    static Bool initialized = NO;
    NSPoint mouse = [NSEvent mouseLocation];
    int x = mouse.x, y = TkMacOSXZeroScreenHeight() - mouse.y;

    /*
     * 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++;
    LastKnownRequestProcessed(display)++;
    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
181
182
183
184
185
186
187










188
189
190
191
192
193
194
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208







+
+
+
+
+
+
+
+
+
+







	    if (initialized) {
		if ([win canBecomeKeyWindow]) {
		    [win makeKeyAndOrderFront:NSApp];
		} else {
		    [win orderFrontRegardless];
		}
	    }

	    /*
	     * Call Tk_UpdatePointer to tell Tk whether the pointer is in the
	     * new window.
	     */

	    NSPoint viewLocation = [view convertPoint:mouse fromView:nil];
	    if (NSPointInRect(viewLocation, NSInsetRect([view bounds], 2, 2))) {
		Tk_UpdatePointer((Tk_Window) winPtr, x, y, [NSApp tkButtonState]);
	    }
	} else {
	    TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);

	    /*
	     * Rebuild the container's clipping region and display
	     * the window.
	     */
296
297
298
299
300
301
302
303

304
305
306
307
308
309
































310
311

312
313
314
315
316
317
318
310
311
312
313
314
315
316

317
318
319




320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361







-
+


-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+







    TkWindow *winPtr = macWin->winPtr;
    TkWindow *parentPtr = winPtr->parentPtr;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(window);

    if (!window) {
	return BadWindow;
    }
    display->request++;
    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(winPtr)) {
	if (!Tk_IsEmbedded(winPtr) &&
		winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
	    [win orderOut:nil];
	    [win setExcludedFromWindowsMenu:YES];
	}
	    winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
	    [win setExcludedFromWindowsMenu:YES];
	    [win orderOut:NSApp];
	    if ([win isKeyWindow]) {

		/*
		 * If we are unmapping the key window then we need to make sure
		 * that a new key window is assigned, if possible.  This is
		 * supposed to happen when a key window is ordered out, but as
		 * noted in tkMacOSXWm.c this does not happen, in spite of
		 * Apple's claims to the contrary.
		 */

		for (NSWindow *w in [NSApp orderedWindows]) {
		    TkWindow *winPtr2 = TkMacOSXGetTkWindow(w);
		    WmInfo *wmInfoPtr;

		    BOOL isOnScreen;

		    if (!winPtr2 || !winPtr2->wmInfoPtr) {
			continue;
		    }
		    wmInfoPtr = winPtr2->wmInfoPtr;
		    isOnScreen = (wmInfoPtr->hints.initial_state != IconicState &&
				  wmInfoPtr->hints.initial_state != WithdrawnState);
		    if (w != win && isOnScreen && [w canBecomeKeyWindow]) {
			[w makeKeyAndOrderFront:NSApp];
			break;
		    }
		}
	    }
	}
	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) {
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+







    Display *display,		/* Display. */
    Window window,		/* Window. */
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    LastKnownRequestProcessed(display)++;
    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 {
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458







-
+







    Window window,		/* Window. */
    int x, int y,
    unsigned int width,
    unsigned int height)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    LastKnownRequestProcessed(display)++;
    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
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511







-
+







XMoveWindow(
    Display *display,		/* Display. */
    Window window,		/* Window. */
    int x, int y)
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;

	if (w) {
	    [w setFrameTopLeftPoint: NSMakePoint(
		    x, TkMacOSXZeroScreenHeight() - y)];
	}
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
640
641
642
643
644
645
646

647
648
649
650
651
652
653
654







-
+







int
XRaiseWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }
631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688







-
+







int
XLowerWindow(
    Display *display,		/* Display. */
    Window window)		/* Window. */
{
    MacDrawable *macWin = (MacDrawable *)window;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {
	/*
	 * TODO: this should generate damage
	 */
    }
670
671
672
673
674
675
676
677

678
679
680
681
682
683
684
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727







-
+







    Window w,			/* Window. */
    unsigned int value_mask,
    TCL_UNUSED(XWindowChanges *))
{
    MacDrawable *macWin = (MacDrawable *)w;
    TkWindow *winPtr = macWin->winPtr;

    display->request++;
    LastKnownRequestProcessed(display)++;

    /*
     * Change the shape and/or position of the window.
     */

    if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
	XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,
808
809
810
811
812
813
814
815

816
817
818
819
820
821
822
851
852
853
854
855
856
857

858
859
860
861
862
863
864
865







-
+







	    HIMutableShapeRef rgn;

	    /*
	     * Start with a region defined by the window bounds.
	     */

	    TkMacOSXWinCGBounds(winPtr, &bounds);
	    rgn = TkMacOSXHIShapeCreateMutableWithRect(&bounds);
	    rgn = HIShapeCreateMutableWithRect(&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
841
842
843
844
845
846
847









848
849
850
851
852
853
854
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906







+
+
+
+
+
+
+
+
+







		}
	    } 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);
		    TkDestroyRegion(r);
		}

		/*
		 * TODO: Here we should handle out of process embedding.
		 */
	    }
	    macWin->aboveVisRgn = HIShapeCreateCopy(rgn);
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
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







-
+















-
+










-
+






-
+







		TkMacOSXUpdateClipRgn(winPtr->parentPtr);
	    } else if (Tk_IsEmbedded(winPtr)) {
		win2Ptr = TkpGetOtherWindow(winPtr);
		if (win2Ptr) {
		    TkMacOSXUpdateClipRgn(win2Ptr);
		}
	    }
	    macWin->aboveVisRgn = TkMacOSXHIShapeCreateEmpty();
	    macWin->aboveVisRgn = HIShapeCreateEmpty();
	}
	if (!macWin->visRgn) {
	    macWin->visRgn = HIShapeCreateCopy(macWin->aboveVisRgn);
	}
	macWin->flags &= ~TK_CLIP_INVALID;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXVisableClipRgn --
 *
 *	This function returns the Macintosh clipping region for the given
 *	window. The caller is responsible for disposing of the returned region
 *	via XDestroyRegion().
 *	via TkDestroyRegion().
 *
 * Results:
 *	The region.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Region
TkRegion
TkMacOSXVisableClipRgn(
    TkWindow *winPtr)
{
    if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(winPtr);
    }
    return (Region) HIShapeCreateMutableCopy(winPtr->privatePtr->visRgn);
    return (TkRegion) HIShapeCreateMutableCopy(winPtr->privatePtr->visRgn);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXInvalidateViewRegion --
 *
969
970
971
972
973
974
975
976

977
978
979
980
981
982
983
1021
1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
1035







-
+







InvalViewRect(
    int msg,
    TCL_UNUSED(HIShapeRef),
    const CGRect *rect,
    void *ref)
{
    static CGAffineTransform t;
    TKContentView *view = ref;
    TKContentView *view = (TKContentView *)ref;
    NSRect dirtyRect;

    if (!view) {
	return paramErr;
    }
    switch (msg) {
    case kHIShapeEnumerateInit:
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
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







-
+
-











-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSWindowForDrawable --
 *
 *	This function returns the NSWindow for a given X drawable, if the
 *	This function returns the NSWindow for a given X drawable.
 *      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(
TkMacOSXDrawable(
    Drawable drawable)
{
    MacDrawable *macWin = (MacDrawable *)drawable;
    NSWindow *result = nil;

    if (!macWin || macWin->flags & TK_IS_PIXMAP) {
	result = nil;
1074
1075
1076
1077
1078
1079
1080
























1081
1082
1083
1084
1085
1086
1087
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








	if (contWinPtr) {
	    result = TkMacOSXGetNSWindowForDrawable((Drawable)contWinPtr->privatePtr);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetDrawablePort --
 *
 *	This function only exists because it is listed in the stubs table.
 *      It is useless.
 *
 * Results:
 *	NULL.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetDrawablePort(
    TCL_UNUSED(Drawable))
{
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXGetNSViewForDrawable/TkMacOSXGetRootControl --
 *
 *	The function name TkMacOSXGetRootControl is being preserved only
1387
1388
1389
1390
1391
1392
1393
1394

1395
1396
1397
1398
1399
1400
1401
1462
1463
1464
1465
1466
1467
1468

1469
1470
1471
1472
1473
1474
1475
1476







-
+







    int width,		/* Dimensions of pixmap. */
    int height,
    int depth)		/* Bits per pixel for pixmap. */
{
    MacDrawable *macPix;

    if (display != NULL) {
	display->request++;
	LastKnownRequestProcessed(display)++;
    }
    macPix = (MacDrawable *)ckalloc(sizeof(MacDrawable));
    macPix->winPtr = NULL;
    macPix->xOff = 0;
    macPix->yOff = 0;
    macPix->visRgn = NULL;
    macPix->aboveVisRgn = NULL;
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
1504
1505
1506
1507
1508
1509
1510

1511
1512





1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525







-
+

-
-
-
-
-













void
Tk_FreePixmap(
    Display *display,		/* Display. */
    Pixmap pixmap)		/* Pixmap to destroy */
{
    MacDrawable *macPix = (MacDrawable *)pixmap;

    display->request++;
    LastKnownRequestProcessed(display)++;
    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:
 */
Changes to macosx/tkMacOSXTest.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
1
2
3
4
5
6



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25

26



27
28
29


30

31
32
33
34
35
36
37






-
-
-
+
+
+















-
+
-

-
-
-
+
+
+
-
-
+
-







/*
 * tkMacOSXTest.c --
 *
 *	Contains commands for platform specific tests for
 *	the Macintosh platform.
 *
 * Copyright (c) 1996 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1996 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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,
static Tcl_ObjCmdProc DebuggerObjCmd;
					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,
static Tcl_ObjCmdProc PressButtonObjCmd;
static Tcl_ObjCmdProc MoveMouseObjCmd;
static Tcl_ObjCmdProc InjectKeyEventObjCmd;
					int objc, Tcl_Obj *const *objv);
static int		MenuBarHeightObjCmd (ClientData dummy, Tcl_Interp *interp,
static Tcl_ObjCmdProc MenuBarHeightObjCmd;
					int objc, Tcl_Obj *const *objv);


/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
58
59
60
61
62
63
64

65
66
67
68
69
70
71
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69







+







     * 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, "movemouse", MoveMouseObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "injectkeyevent", InjectKeyEventObjCmd, NULL, NULL);
    Tcl_CreateObjCommand(interp, "menubarheight", MenuBarHeightObjCmd, NULL, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
83
84
85
86
87
88
89
90
91
92
93




94
95
96
97
98
99
100
81
82
83
84
85
86
87




88
89
90
91
92
93
94
95
96
97
98







-
-
-
-
+
+
+
+







 *
 *----------------------------------------------------------------------
 */

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
static int
DebuggerObjCmd(
    ClientData clientData,		/* Not used. */
    Tcl_Interp *interp,			/* Not used. */
    int objc,				/* Not used. */
    Tcl_Obj *const objv[])			/* Not used. */
    TCL_UNUSED(void *),		/* Not used. */
    TCL_UNUSED(Tcl_Interp *),			/* Not used. */
    TCL_UNUSED(int),				/* Not used. */
    TCL_UNUSED(Tcl_Obj *const *)			/* Not used. */
{
    Debugger();
    return TCL_OK;
}
#endif

/*
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+







    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));
    Tcl_SetObjResult(interp, Tcl_NewIntObj(height));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkTestLogDisplay --
144
145
146
147
148
149
150

151
152
153
154
155
156
157
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156







+







 *      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 &&
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206







-
+



















-







 *
 * 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
 *      their timestamp property set to 0 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};

230
231
232
233
234
235
236


237
238


































































































239
240
241
242
243
244
245
246


247
248

249
250

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
228
229
230
231
232
233
234
235
236


237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340


341
342
343

344
345

346
347




















348
349
350
351
352
353
354







+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
-
+
+

-
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	}
    }
    pt.x = loc.x = x;
    pt.y = y;
    loc.y = ScreenHeight - y;

    /*
     *  We set the timestamp to 0 as a signal to tkProcessMouseEvent.
     */
     *  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:0
	windowNumber:0
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0];
    [NSApp postEvent:motion atStart:NO];
    press = [NSEvent mouseEventWithType:NSLeftMouseDown
	location:loc
	modifierFlags:0
	timestamp:0
	windowNumber:0
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0];
    [NSApp postEvent:press atStart:NO];
    release = [NSEvent mouseEventWithType:NSLeftMouseUp
	location:loc
	modifierFlags:0
	timestamp:0
	windowNumber:0
	context:nil
	eventNumber:0
	clickCount:1
	pressure:0];
    [NSApp postEvent:release atStart:NO];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * MoveMouseObjCmd --
 *
 *	This Tcl command simulates a mouse motion to a specific screen
 *      location.  It injects an NSEvent into the NSApplication event queue,
 *      as opposed to adding events to the Tcl queue as event generate would
 *      do.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
MoveMouseObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    int x = 0, y = 0, i, value;
    CGPoint pt;
    NSPoint loc;
    NSEvent *motion;
    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 timestamp to 0 as a signal to tkProcessMouseEvent.
     */

    CGWarpMouseCursorPosition(pt);
    motion = [NSEvent mouseEventWithType:NSMouseMoved
	location:loc
	modifierFlags:0
	timestamp:GetCurrentEventTime()
	windowNumber:signal
	timestamp:0
	windowNumber:0
	context:nil
	eventNumber:signal
	eventNumber:0
	clickCount:1
	pressure:0.0];
	pressure: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,
293
294
295
296
297
298
299
300
301


302
303
304
305
306
307
308
369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
384







-
-
+
+







    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) {
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
            sizeof(char *), "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);
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387
388
389
390
448
449
450
451
452
453
454

455
456
457
458
459
460
461
462
463
464
465
466







-
+











        modifierFlags:mods
	timestamp:GetCurrentEventTime()
	windowNumber:0
	context:nil
	characters:chars
	charactersIgnoringModifiers:unmod
	isARepeat:NO
	keyCode:macKC.v.virtual];
	keyCode:macKC.v.virt];
    [NSApp postEvent:keyEvent atStart:NO];
    return TCL_OK;
}
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */
Changes to macosx/tkMacOSXWindowEvent.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
1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25






-
-
-
-
+
+
+
+







-
+







/*
 * tkMacOSXWindowEvent.c --
 *
 *	This file defines the routines for both creating and handling Window
 *	Manager class events for Tk.
 *
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Kevin Walzer/WordTech Communications LLC.
 * Copyright (c) 2015 Marc Culler.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * 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 "tkMacOSXWm.h"
#include "tkMacOSXInt.h"
#include "tkMacOSXEvent.h"
#include "tkMacOSXDebug.h"
#include "tkMacOSXConstants.h"

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_EVENTS
#define TK_MAC_DEBUG_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
46
47
48
49
50
51
52

53
54


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







-
+

-
-


+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+

-
+






-
+









@implementation TKApplication(TKWindowEvent)

- (void) windowActivation: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    BOOL activate = [[notification name]
	    isEqualToString:NSWindowDidBecomeKeyNotification];
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    NSString *name = [notification name];
    Bool flag = [name isEqualToString:NSWindowDidBecomeKeyNotification];
    if (winPtr && flag) {
	NSPoint location = [NSEvent mouseLocation];
	int x = location.x;
	int y = floor(TkMacOSXZeroScreenHeight() - location.y);
	/*
	 * The Tk event target persists when there is no key window but
	 * gets reset when a new window becomes the key window.
	 */

	[NSApp setTkEventTarget: winPtr];

	/*
	 * Call Tk_UpdatePointer if the pointer is in the window.
	 */

	NSView *view = [w contentView];
	NSPoint viewLocation = [view convertPoint:location fromView:nil];
	if (NSPointInRect(viewLocation, NSInsetRect([view bounds], 2, 2))) {
	    Tk_UpdatePointer((Tk_Window) winPtr, x, y, [NSApp tkButtonState]);
	}
    }
    if (winPtr && Tk_IsMapped(winPtr)) {
	GenerateActivateEvents(winPtr, activate);
	GenerateActivateEvents(winPtr, flag);
    }
}

- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    BOOL movedOnly = [[notification name]
	    isEqualToString:NSWindowDidMoveNotification];
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133







-
+







    }

}

- (void) windowExpanded: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
156
157
158
159
160
161
162
163

164



165
166
167
168
169
170
171

172



173
174
175
176
177
178
179

180
181
182
183
184

185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226







-
+

+
+
+






-
+

+
+
+






-
+





+







-
+








    return proposedSize;
}

- (void) windowEnteredFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (![[notification object] respondsToSelector: @selector (tkLayoutChanged)]) {
	return;
    }
    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowExitedFullScreen: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if (![[notification object] respondsToSelector: @selector (tkLayoutChanged)]) {
	return;
    }
    [(TKWindow *)[notification object] tkLayoutChanged];
}

- (void) windowCollapsed: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state = IconicState;
	Tk_UnmapWindow((Tk_Window)winPtr);
    }
}

- (BOOL) windowShouldClose: (NSWindow *) w
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, w);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), w);
#endif
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	TkGenWMDestroyEvent((Tk_Window)winPtr);
    }

208
209
210
211
212
213
214
215
216


217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234











235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
235
236
237
238
239
240
241


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

278






279
280
281
282

283
284
285
286
287
288
289
290







-
-
+
+


















+
+
+
+
+
+
+
+
+
+
+





-
+
-
-
-
-
-
-




-
+







- (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, *)) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	if (@available(macOS 10.14, *)) {
	    [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)) {}
    }
}

- (void) windowLiveResize: (NSNotification *) notification
{
    NSString *name = [notification name];
    if ([name isEqualToString:NSWindowWillStartLiveResizeNotification]) {
	// printf("Starting live resize.\n");
    } else if ([name isEqualToString:NSWindowDidEndLiveResizeNotification]) {
	[self setTkLiveResizeEnded:YES];
	// printf("Ending live resize\n");
    }
}

#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window)winPtr);
    }
}
270
271
272
273
274
275
276


277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293










294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310




311
312
313
314
315
316
317
318
319






320
321
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318


319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387







+
+

-
+






-
-







+
+
+
+
+
+
+
+
+
+









-
+







+
+
+
+








-
+
+
+
+
+
+









-
+







    observe(NSWindowDidResignKeyNotification, windowActivation:);
    observe(NSWindowDidMoveNotification, windowBoundsChanged:);
    observe(NSWindowDidResizeNotification, windowBoundsChanged:);
    observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
    observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);

#if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070)
#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


/*
 * Idle task which forces focus to a particular window.
 */

static void RefocusGrabWindow(void *data) {
    TkWindow *winPtr = (TkWindow *) data;
    TkpChangeFocus(winPtr, 1);
}

#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);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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.
     * If one of the windows is the grab window for its display we focus
     * it.  This is done as at idle, in case the app was reactivated by
     * clicking a different window.  In that case we need to wait until the
     * mouse event has been processed before focusing the grab 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];
	    [win orderOut:NSApp];
	}
	if (winPtr->dispPtr->grabWinPtr == winPtr) {
	    Tcl_DoWhenIdle(RefocusGrabWindow, winPtr);
	} else {
	    [[self keyWindow] orderFront: self];
	}
    }
}

- (void) applicationDeactivate: (NSNotification *) notification
{
    (void)notification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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.
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467







-
+




















-
+




















-
+







    return NO;
}


- (void) applicationShowHide: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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.
 *      redraw, via an 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
910
911
912
913
914
915
916
917


























































918
919
920
921
922


923
924
925
926
927
928
929
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








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





+
+







    TCL_UNUSED(void *),
    XEvent *eventPtr)
{
    return (eventPtr->type==ConfigureNotify ? TK_PROCESS_EVENT : TK_DEFER_EVENT);
}

@implementation TKContentView(TKWindowEvent)

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
	/*
	 * The layer must exist before we set wantsLayer to YES.
	 */

	self.layer = [CALayer layer];
	self.wantsLayer = YES;
	self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
	self.layer.contentsGravity = self.layer.contentsAreFlipped ?
	    kCAGravityTopLeft : kCAGravityBottomLeft;

	/*
	 * Nothing gets drawn at all if the layer does not have a delegate.
	 * Currently, we do not implement any methods of the delegate, however.
	 */

	self.layer.delegate = (id) self;
	trackingArea = [[NSTrackingArea alloc]
			   initWithRect:[self bounds]
				options:(NSTrackingMouseEnteredAndExited |
					 NSTrackingMouseMoved |
					 NSTrackingEnabledDuringMouseDrag |
					 NSTrackingInVisibleRect |
					 NSTrackingActiveAlways)
				  owner:self
			       userInfo:nil];
        [self addTrackingArea:trackingArea];
    }
    return self;
}

/*
 * We will just use drawRect.
 */

- (BOOL) wantsUpdateLayer
{
    return NO;
}

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
- (void) viewDidChangeBackingProperties
{

    /*
     * Make sure that the layer uses a contentScale that matches the
     * backing scale factor of the screen.  This avoids blurry text when
     * the view is on a Retina display, as well as incorrect size when
     * the view is on a normal display.
     */

    self.layer.contentsScale = self.window.screen.backingScaleFactor;
}
#endif

- (void) addTkDirtyRect: (NSRect) rect
{
    _tkNeedsDisplay = YES;
    _tkDirtyRect = NSUnionRect(_tkDirtyRect, rect);
    [NSApp setNeedsToDraw:YES];
    [self setNeedsDisplay:YES];
    [[self layer] setNeedsDisplay];
}

- (void) clearTkDirtyRect
{
    _tkNeedsDisplay = NO;
    _tkDirtyRect = NSZeroRect;
    [NSApp setNeedsToDraw:NO];
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
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







-
+

-
+
-
-
-
-
-
-
-
-
-



-
-
-
-
-
-
-
-
-
-
-
-











-
+







+
+


















-
+

-
+








-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+







	return;
    }
    NSAppearanceName effectiveAppearanceName = [[self effectiveAppearance] name];
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
    static const char *defaultColor = NULL;

    if (effectiveAppearanceName == NSAppearanceNameAqua) {
	Tk_SendVirtualEvent(tkwin, "LightAqua", NULL);
	TkSendVirtualEvent(tkwin, "LightAqua", NULL);
    } else if (effectiveAppearanceName == NSAppearanceNameDarkAqua) {
	Tk_SendVirtualEvent(tkwin, "DarkAqua", NULL);
	TkSendVirtualEvent(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));
    TkSendVirtualEvent(tkwin, "AppearanceChanged", Tcl_NewStringObj(data, -1));
}

- (void)observeValueForKeyPath:(NSString *)keyPath
		      ofObject:(id)object
			change:(NSDictionary *)change
		       context:(void *)context
{
    (void) change;
    (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);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), sender);
#endif
    XVirtualEvent event;
    union {XEvent general; XVirtualEvent virt;} 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();
    bzero(&event, sizeof(event));
    event.virt.type = VirtualEvent;
    event.virt.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    event.virt.send_event = false;
    event.virt.display = Tk_Display(tkwin);
    event.virt.event = Tk_WindowId(tkwin);
    event.virt.root = XRootWindow(Tk_Display(tkwin), 0);
    event.virt.subwindow = None;
    event.virt.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);
	    &event.virt.x_root, &event.virt.y_root, &x, &y, &event.virt.state);
    Tk_TopCoordsToWindow(tkwin, x, y, &event.virt.x, &event.virt.y);
    event.virt.same_screen = true;
    event.virt.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL);
}

/*
 * On Catalina this is never called and drawRect clips to the rect that
 * is passed to it by AppKit.
 */

1235
1236
1237
1238
1239
1240
1241
1242

1243
1244
1245
1246
1247
1248
1249
1327
1328
1329
1330
1331
1332
1333

1334
1335
1336
1337
1338
1339
1340
1341







-
+







 */

- (void) keyDown: (NSEvent *) theEvent
{
    (void)theEvent;

#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_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
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
1
2
3
4
5
6
7





8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28







-
-
-
-
-
+
+
+
+
+








-
+







/*
 * 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.
 * Copyright © 1994-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 2010 Kevin Walzer/WordTech Communications LLC.
 * Copyright © 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 "tkMacOSXEvent.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.
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193







-
+







 */

static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
    NULL,			/* lostSlaveProc */
};

/*
 * The following keeps state for Aqua dock icon bounce notification.
 */

static int tkMacOSXWmAttrNotifyVal = 0;
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372







+




















-







}
#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)

403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417







-
+







	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)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
- (void)toggleTabBar:(id)sender
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
    if (!winPtr) {
	return;
    }
    [super toggleTabBar:sender];
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
742
743
744
745
746
747
748




































































749
750
751
752
753
754
755







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








    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 --
 *
 *	This procedure is invoked to map a top-level window. This module gets
 *	a chance to update all window-manager-related information in
 *	properties before the window manager sees the map event and checks the
 *	properties. It also gets to decide whether or not to even map the
 *	window after all.
913
914
915
916
917
918
919
920

921
922
923
924
925
926
927
845
846
847
848
849
850
851

852
853
854
855
856
857
858
859







-
+







    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);
    Tk_HandleEvent(&event);
}

/*
 *----------------------------------------------------------------------
 *
 * 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
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







+
+
+
-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+







 */

void
TkWmUnmapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * unmapped. */
{
    winPtr->flags &= ~TK_MAPPED;
    if ((winPtr->window != None)
	    && (XUnmapWindow(winPtr->display, winPtr->window) == Success)) {
    XEvent event;
	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;
	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);
	Tk_HandleEvent(&event);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmDeadWindow --
 *
1046
1047
1048
1049
1050
1051
1052


























1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







-








    while (wmPtr->transientPtr != NULL) {
	Transient *transientPtr = wmPtr->transientPtr;

	wmPtr->transientPtr = transientPtr->nextPtr;
	ckfree(transientPtr);
    }

    deadNSWindow = (TKWindow *)wmPtr->window;

    /*
     * Remove references to the Tk window from the mouse event processing
     * state which is recorded in the NSApplication object.
     */

    if (winPtr == [NSApp tkPointerWindow]) {
	NSWindow *w;
	NSPoint mouse = [NSEvent mouseLocation];
	[NSApp setTkPointerWindow:nil];
	for (w in [NSApp orderedWindows]) {
	    if (w == deadNSWindow) {
		continue;
	    }
	    if (NSPointInRect(mouse, [w frame])) {
		TkWindow *winPtr2 = TkMacOSXGetTkWindow(w);
		int x = mouse.x, y = TkMacOSXZeroScreenHeight() - mouse.y;
		[NSApp setTkPointerWindow:winPtr2];
		Tk_UpdatePointer((Tk_Window) winPtr2, x, y,
				 [NSApp tkButtonState]);
		break;
	    }
	}
    }

    /*
     * 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;
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
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







+
+
+
+
+
+
+












+



+
+










+
+
+
+
+

-







	 * 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.
	 */


	/*
	 * Fix bug 5692042764:
	 * set tkEventTarget to NULL when there is no window to send Tk events to.
	 */
	TkWindow *newTkEventTarget = NULL;

	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];
		newTkEventTarget = TkMacOSXGetTkWindow(w);
		break;
	    }
	}

	[NSApp setTkEventTarget:newTkEventTarget];

	/*
	 * Prevent zombies on systems with a TouchBar.
	 */

	if (deadNSWindow == [NSApp keyWindow]) {
	    [NSApp _setKeyWindow:nil];
	    [NSApp _setMainWindow:nil];
	}
	[deadNSWindow close];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
	NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
	[preferences removeObserver:deadNSWindow.contentView
		      forKeyPath:@"AppleHighlightColor"];
#endif
	[deadNSWindow release];
	[NSApp _resetAutoreleasePool];

#if DEBUG_ZOMBIES > 1
	fprintf(stderr, "================= Pool dump ===================\n");
	[NSAutoreleasePool showPools];
#endif

    }
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
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







-
+
+

















-
+















-
+


-
+







	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;
    int index;
    int length;
    char *argv1;
    TkWindow *winPtr;

    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", 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));
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(wmTracing));
	    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) {
	    != TCL_OK) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr)
    if (winPtr && !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;
    }
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368




1369
1370
1371
1372
1373
1374
1375
1332
1333
1334
1335
1336
1337
1338




1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349







-
-
-
-
+
+
+
+







		"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);
	    results[0] = Tcl_NewIntObj(wmPtr->minAspect.x);
	    results[1] = Tcl_NewIntObj(wmPtr->minAspect.y);
	    results[2] = Tcl_NewIntObj(wmPtr->maxAspect.x);
	    results[3] = Tcl_NewIntObj(wmPtr->maxAspect.y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
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
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







-
+











-
+




















-
+







	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)
#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]) {
	    [macWindow setDocumentEdited:boolean];
	    [macWindow setDocumentEdited:(BOOL)boolean];
	}
	break;
    case WMATT_NOTIFY:
	if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (boolean == !tkMacOSXWmAttrNotifyVal) {
	    static NSInteger request = -1;

	    if (request >= 0) {
		[NSApp cancelUserAttentionRequest:request];
		request = -1;
	    }
	    if (boolean) {
		request = [NSApp requestUserAttention:NSCriticalRequest];
	    }
	    tkMacOSXWmAttrNotifyVal = boolean;
	}
	break;
    case WMATT_TITLEPATH: {
	const char *path = Tcl_FSGetNativePath(value);
	const char *path = (const char *)Tcl_FSGetNativePath(value);
	NSString *filename = @"";

	if (path && *path) {
	    filename = [NSString stringWithUTF8String:path];
	}
	[macWindow setRepresentedFilename:filename];
	break;
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
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







-
+


-
+






-
+


-
+







    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);
	result = Tcl_NewBooleanObj([macWindow isDocumentEdited]);
	break;
    case WMATT_NOTIFY:
	result = Tcl_NewWideIntObj(tkMacOSXWmAttrNotifyVal != 0);
	result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal);
	break;
    case WMATT_TITLEPATH:
	result = Tcl_NewStringObj([[macWindow representedFilename] UTF8String],
		-1);
	break;
    case WMATT_TOPMOST:
	result = Tcl_NewWideIntObj((wmPtr->flags & WM_TOPMOST) != 0);
	result = Tcl_NewBooleanObj(wmPtr->flags & WM_TOPMOST);
	break;
    case WMATT_TRANSPARENT:
	result = Tcl_NewWideIntObj((wmPtr->flags & WM_TRANSPARENT) != 0);
	result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT);
	break;
    case WMATT_TYPE:
	result = Tcl_NewStringObj("unsupported", -1);
	break;
    case _WMATT_LAST_ATTRIBUTE:
    default:
	break;
1608
1609
1610
1611
1612
1613
1614
1615

1616
1617
1618
1619
1620
1621
1622
1582
1583
1584
1585
1586
1587
1588

1589
1590
1591
1592
1593
1594
1595
1596







-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAttributesCmd(
    TCL_UNUSED(Tk_Window),		/* Main window of the application. */
    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;
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
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







-
+







-
+








-
+







    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));
		    WmGetAttribute(winPtr, macWindow, (WmAttribute)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));
	Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, (WmAttribute)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])
	    if (WmSetAttribute(winPtr, macWindow, interp, (WmAttribute)attribute, objv[i+1])
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	}
    } else {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");
	return TCL_ERROR;
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
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







-
+
+















-
+







    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;
    int i, windowObjc;
    int 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]));
		    TkNewWindowObj((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;
1799
1800
1801
1802
1803
1804
1805
1806

1807
1808
1809
1810
1811
1812
1813
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785
1786
1787
1788







-
+







    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
     * 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;
}

/*
1938
1939
1940
1941
1942
1943
1944


1945
1946
1947
1948
1949
1950
1951
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928







+
+







		    ((transientPtr->flags & WITHDRAWN_BY_CONTAINER) != 0)) {
		TkpWmSetState(winPtr2, NormalState);
		transientPtr->flags &= ~WITHDRAWN_BY_CONTAINER;
	    }
	}
    }

    [[win contentView] setNeedsDisplay:YES];
    Tcl_DoWhenIdle(TkMacOSXDrawAllViews, NULL);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * WmFocusmodelCmd --
2098
2099
2100
2101
2102
2103
2104
2105

2106
2107
2108
2109
2110
2111
2112
2075
2076
2077
2078
2079
2080
2081

2082
2083
2084
2085
2086
2087
2088
2089







-
+







	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);
    snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
-
-
-
+
+
+
+










-
+







		"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);
	    results[0] = Tcl_NewIntObj(wmPtr->reqGridWidth);
	    results[1] = Tcl_NewIntObj(wmPtr->reqGridHeight);
	    results[2] = Tcl_NewIntObj(wmPtr->widthInc);
	    results[3] = Tcl_NewIntObj(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.
	 */

	wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
	wmPtr->sizeHintsFlags &= ~PBaseSize;
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
2446
2447
2448
2449
2450
2451
2452
2453

2454
2455
2456
2457
2458
2459

2460
2461
2462
2463
2464
2465
2466
2423
2424
2425
2426
2427
2428
2429

2430
2431
2432
2433
2434
2435

2436
2437
2438
2439
2440
2441
2442
2443







-
+





-
+







    } 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\"",
		"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",
		"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) {
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
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







-
+













-







    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;
    int width, height;
    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;
	}
    }

2721
2722
2723
2724
2725
2726
2727
2728
2729


2730
2731
2732
2733
2734
2735
2736
2697
2698
2699
2700
2701
2702
2703


2704
2705
2706
2707
2708
2709
2710
2711
2712







-
-
+
+







	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);
	    results[0] = Tcl_NewIntObj(wmPtr->hints.icon_x);
	    results[1] = Tcl_NewIntObj(wmPtr->hints.icon_y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconPositionHint;
2778
2779
2780
2781
2782
2783
2784
2785

2786
2787
2788
2789
2790
2791
2792
2754
2755
2756
2757
2758
2759
2760

2761
2762
2763
2764
2765
2766
2767
2768







-
+







    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));
	    Tcl_SetObjResult(interp, TkNewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }

    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
2821
2822
2823
2824
2825
2826
2827
2828

2829
2830
2831
2832
2833
2834
2835
2797
2798
2799
2800
2801
2802
2803

2804
2805
2806
2807
2808
2809
2810
2811







-
+







	    NSWindow *win = TkMacOSXGetNSWindowForDrawable(oldIcon->window);

	    /*
	     * The old icon should be withdrawn.
	     */

	    TkpWmSetState(oldIcon, WithdrawnState);
	    [win orderOut:nil];
	    [win orderOut:NSApp];
    	    [win setExcludedFromWindowsMenu:YES];
	    wmPtr3->iconFor = NULL;
	}
	Tk_MakeWindowExist(tkwin2);
	wmPtr->hints.icon_window = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= IconWindowHint;
	wmPtr->icon = tkwin2;
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
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







-
-
-
+
+
+

















+
+
+
+
+
+
+
+
+
+
+
+







 *	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(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;
	}

	/*
	 * Draw the managed widget at the top left corner of its toplevel.
	 * See [4a40c6cace].
	 */

	if (macWin) {
	    winPtr->changes.x -= macWin->xOff;
	    winPtr->changes.y -= macWin->yOff;
	    XMoveWindow(winPtr->display, winPtr->window, 0, 0);
	}

	TkFocusSplit(winPtr);
	Tk_UnmapWindow(frameWin);
	if (wmPtr == NULL) {
	    TkWmNewWindow(winPtr);
	    if (winPtr->window == None) {
		Tk_MakeWindowExist((Tk_Window)winPtr);
		macWin = (MacDrawable *)winPtr->window;
2946
2947
2948
2949
2950
2951
2952
2953
2954


2955
2956
2957
2958
2959
2960
2961
2934
2935
2936
2937
2938
2939
2940


2941
2942
2943
2944
2945
2946
2947
2948
2949







-
-
+
+







	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMaxSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	results[0] = Tcl_NewIntObj(width);
	results[1] = Tcl_NewIntObj(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;
3000
3001
3002
3003
3004
3005
3006
3007
3008


3009
3010
3011
3012
3013
3014
3015
2988
2989
2990
2991
2992
2993
2994


2995
2996
2997
2998
2999
3000
3001
3002
3003







-
-
+
+







	return TCL_ERROR;
    }

    if (objc == 3) {
	Tcl_Obj *results[2];

	GetMinSize(winPtr, &width, &height);
	results[0] = Tcl_NewWideIntObj(width);
	results[1] = Tcl_NewWideIntObj(height);
	results[0] = Tcl_NewIntObj(width);
	results[1] = Tcl_NewIntObj(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;
3053
3054
3055
3056
3057
3058
3059
3060

3061
3062
3063
3064
3065
3066
3067
3041
3042
3043
3044
3045
3046
3047

3048
3049
3050
3051
3052
3053
3054
3055







-
+







    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));
		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;
3271
3272
3273
3274
3275
3276
3277
3278
3279

3280
3281

3282
3283
3284
3285
3286
3287
3288
3259
3260
3261
3262
3263
3264
3265


3266


3267
3268
3269
3270
3271
3272
3273
3274







-
-
+
-
-
+







	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[0] = Tcl_NewBooleanObj(!(wmPtr->flags & WM_WIDTH_NOT_RESIZABLE));
	results[1] = Tcl_NewWideIntObj(
		(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) == 0);
	results[1] = Tcl_NewBooleanObj(!(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;
3424
3425
3426
3427
3428
3429
3430
3431

3432
3433
3434
3435
3436
3437
3438
3410
3411
3412
3413
3414
3415
3416

3417
3418
3419
3420
3421
3422
3423
3424







-
+








    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));
		    TkNewWindowObj((Tk_Window)*windowPtr));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	    ckfree(windows);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
3499
3500
3501
3502
3503
3504
3505
3506

3507
3508
3509
3510
3511
3512
3513
3485
3486
3487
3488
3489
3490
3491

3492
3493
3494
3495
3496
3497
3498
3499







-
+







	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result != 0));
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
3544
3545
3546
3547
3548
3549
3550
3551

3552
3553
3554
3555
3556
3557
3558

3559
3560
3561
3562
3563
3564
3565
3530
3531
3532
3533
3534
3535
3536

3537
3538
3539
3540
3541
3542
3543

3544
3545
3546
3547
3548
3549
3550
3551







-
+






-
+







	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\"",
		    "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",
		    "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) {
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
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







-
+















+







    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?");
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	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;
	}
	RemoveTransient(winPtr);
	containerPtr = (TkWindow*) container;
	while (!Tk_TopWinHierarchy(containerPtr)) {
            /*
             * Ensure that the container window is actually a Tk toplevel.
             */

            containerPtr = containerPtr->parentPtr;
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
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







-
+






-
+


-
+








	/*
	 * 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",
		    "can't make \"%s\" a master: 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) {
	    w = (TkWindow *)w->wmInfoPtr->container) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    "setting \"%s\" as master creates a transient/master cycle",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}

	/*
3995
3996
3997
3998
3999
4000
4001
4002

4003
4004
4005
4006
4007
4008
4009
4010
3982
3983
3984
3985
3986
3987
3988

3989

3990
3991
3992
3993
3994
3995
3996







-
+
-







	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
	    && ((wmPtr->sizeHintsFlags & PBaseSize) == PBaseSize)) {
		    == (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
4026
4027
4028
4029
4030
4031
4032
4033

4034
4035
4036
4037
4038
4039
4040
4012
4013
4014
4015
4016
4017
4018

4019
4020
4021
4022
4023
4024
4025
4026







-
+







     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    wmPtr->sizeHintsFlags |= PBaseSize;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

4074
4075
4076
4077
4078
4079
4080
4081

4082
4083
4084
4085
4086
4087
4088
4060
4061
4062
4063
4064
4065
4066

4067
4068
4069
4070
4071
4072
4073
4074







-
+







    }
    wmPtr = winPtr->wmInfoPtr;
    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
    wmPtr->sizeHintsFlags &= ~PBaseSize;
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
4114
4115
4116
4117
4118
4119
4120
4121

4122
4123
4124
4125
4126
4127
4128
4100
4101
4102
4103
4104
4105
4106

4107
4108
4109
4110
4111
4112
4113
4114







-
+







 */

static void
TopLevelEventProc(
    ClientData clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    TkWindow *winPtr = clientData;
    TkWindow *winPtr = (TkWindow *)clientData;

    winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE;
    if (eventPtr->type == DestroyNotify) {
	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
4200
4201
4202
4203
4204
4205
4206
4207

4208
4209
4210
4211
4212
4213
4214
4186
4187
4188
4189
4190
4191
4192

4193
4194
4195
4196
4197
4198
4199
4200







-
+







 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
{
    TkWindow *winPtr = clientData;
    TkWindow *winPtr = (TkWindow *)clientData;
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, min, max;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    if (wmPtr->flags & WM_FULLSCREEN) {
	return;
4619
4620
4621
4622
4623
4624
4625





















4626
4627
4628
4629
4630
4631
4632
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		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 container 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.
	     */
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4788
4789
4790
4791
4792
4793
4794

4795
4796
4797
4798
4799
4800

4801
4802
4803
4804
4805
4806
4807







-






-







    int *newX, int *newY)	/* Coordinates of point in the upperMost child
				 * of tkWin containing (rootX,rootY) */
{
    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;

	/*
	 * Container windows cannot have children. So if it is a container,
	 * look there, otherwise inspect the children.
	 */

	if (Tk_IsContainer(winPtr)) {
5180
5181
5182
5183
5184
5185
5186
5187

5188
5189
5190
5191
5192
5193
5194
5185
5186
5187
5188
5189
5190
5191

5192
5193
5194
5195
5196
5197
5198
5199







-
+







	ckfree(oldPtr);
    }

    topPtr->wmInfoPtr->cmapList = newPtr;
    topPtr->wmInfoPtr->cmapCount = count+1;

    /*
     * On the Macintosh all of this is just an excercise in compatability as
     * 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.
     */
}

/*
 *----------------------------------------------------------------------
 *
5415
5416
5417
5418
5419
5420
5421
5422

5423
5424
5425
5426
5427
5428
5429
5420
5421
5422
5423
5424
5425
5426

5427
5428
5429
5430
5431
5432
5433
5434







-
+







    TkWindow *winPtr,
    Tk_Uid titleUid)
{
    if (Tk_IsEmbedded(winPtr)) {
	return;
    }

    NSString *title = [[NSString alloc] initWithUTF8String:titleUid];
    NSString *title = [[TKNSString alloc] initWithTclUtfBytes:titleUid length:-1];
    [TkMacOSXGetNSWindowForDrawable(winPtr->window) setTitle:title];
    [title release];
}

/*
 *----------------------------------------------------------------------
 *
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512






5513
5514
5515
5516
5517
5518
5519
5505
5506
5507
5508
5509
5510
5511

5512
5513
5514


5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527







-



-
-
+
+
+
+
+
+







 */

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);
    if (window) {
	TkDisplay *dispPtr = TkGetDisplayList();
	return Tk_IdToWindow(dispPtr->display, window);
    } else {
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXIsWindowZoomed --
 *
5558
5559
5560
5561
5562
5563
5564
5565
5566


5567
5568
5569
5570
5571
5572
5573
5566
5567
5568
5569
5570
5571
5572


5573
5574
5575
5576
5577
5578
5579
5580
5581







-
-
+
+







 */

int
TkMacOSXZoomToplevel(
    void *whichWindow,		/* The Macintosh window to zoom. */
    short zoomPart)		/* Either inZoomIn or inZoomOut */
{
    NSWindow *window = whichWindow;
    TkWindow *winPtr = TkMacOSXGetTkWindow(window);
    NSWindow *window = (NSWindow *)whichWindow;
    TkWindow *winPtr = (TkWindow *)TkMacOSXGetTkWindow(window);
    WmInfo *wmPtr;

    if (!winPtr || !winPtr->wmInfoPtr) {
	return false;
    }
    wmPtr = winPtr->wmInfoPtr;
    if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
5616
5617
5618
5619
5620
5621
5622
5623

5624
5625
5626
5627
5628
5629
5630
5624
5625
5626
5627
5628
5629
5630

5631
5632
5633
5634
5635
5636
5637
5638







-
+







{
    static const char *const subcmds[] = {
	"style", "tabbingid", "appearance", "isdark", NULL
    };
    enum SubCmds {
	TKMWS_STYLE, TKMWS_TABID, TKMWS_APPEARANCE, TKMWS_ISDARK
    };
    Tk_Window tkwin = clientData;
    Tk_Window tkwin = (Tk_Window)clientData;
    TkWindow *winPtr;
    int index;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
	return TCL_ERROR;
    }
5785
5786
5787
5788
5789
5790
5791
5792


5793
5794
5795
5796
5797
5798
5799
5793
5794
5795
5796
5797
5798
5799

5800
5801
5802
5803
5804
5805
5806
5807
5808







-
+
+







	{ "canJoinAllSpaces",	tkCanJoinAllSpacesAttribute		     },
	{ "moveToActiveSpace",	tkMoveToActiveSpaceAttribute		     },
	{ "nonActivating",	tkNonactivatingPanelAttribute		     },
	{ "hud",		tkHUDWindowAttribute			     },
	{ NULL, 0 }
    };

    int index, i;
    int index;
    int  i;
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (objc == 3) {
	Tcl_Obj *attributeList, *newResult = NULL;
	UInt64 attributes;

	for (i = 0; classMap[i].strValue != NULL; i++) {
5909
5910
5911
5912
5913
5914
5915
5916







5917
5918
5919
5920
5921
5922
5923
5918
5919
5920
5921
5922
5923
5924

5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938







-
+
+
+
+
+
+
+







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)
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
    (void) interp;
    (void) winPtr;
    (void) objc;
    (void) objv;
    return TCL_OK;
#else
    Tcl_Obj *result = NULL;
    NSString *idString;
    NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);
    if (win) {
	idString = win.tabbingIdentifier;
	result = Tcl_NewStringObj(idString.UTF8String, [idString length]);
    }
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
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







-

+












-
+







		&& [win tab]
#endif
		) {
	    [win moveTabToNewWindow:nil];
	}
	return TCL_OK;
    }
#endif
    return TCL_ERROR;
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * 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?
 *	    tk::unsupported::MacWindowStyle appearance window ?newAppearance?
 *
 *      Allowed appearance names are "aqua", "darkaqua", and "auto".
 *
 * Results:
 *      Returns the appearance setting of the window prior to calling this
 *	function.
 *
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







-
+
+
+
+
+
+
+







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
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 1090
    (void) interp;
    (void) winPtr;
    (void) objc;
    (void) objv;
    return TCL_OK;
#else
    static const char *const appearanceStrings[] = {
	"aqua", "darkaqua", "auto", NULL
    };
    enum appearances {
	APPEARANCE_AQUA, APPEARANCE_DARKAQUA, APPEARANCE_AUTO
    };
    Tcl_Obj *result = NULL;
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
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







-
-
-
+
+
+



















-
-







    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;
        }
		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 --
6138
6139
6140
6141
6142
6143
6144

6145







6146
6147
6148
6149
6150
6151
6152
6157
6158
6159
6160
6161
6162
6163
6164

6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178







+
-
+
+
+
+
+
+
+







	if (contWinPtr != NULL) {
	    TkMacOSXMakeRealWindowExist(
		    contWinPtr->privatePtr->toplevel->winPtr);
	    macWin->flags |= TK_HOST_EXISTS;
	    return;
	}

	if (tkMacOSXEmbedHandler == NULL) {
	Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
	    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.
	 */
    }

6193
6194
6195
6196
6197
6198
6199















6200
6201
6202
6203

6204
6205
6206
6207
6208
6209
6210
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+







    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];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];

    /*
     * AppKit calls the viewDidChangeEffectiveAppearance 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:contentView
		  forKeyPath:@"AppleHighlightColor"
		     options:NSKeyValueObservingOptionNew
		     context:NULL];
#endif
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setAcceptsMouseMovedEvents:NO];
    [window setReleasedWhenClosed:NO];
    if (styleMask & NSUtilityWindowMask) {
	[(TKPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
6229
6230
6231
6232
6233
6234
6235

6236
6237
6238
6239
6240
6241
6242
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284







+







    if (overrideRedirect) {
    	XSetWindowAttributes atts;

    	atts.override_redirect = True;
    	Tk_ChangeWindowAttributes((Tk_Window)winPtr, CWOverrideRedirect, &atts);
    	ApplyContainerOverrideChanges(winPtr, NULL);
    }
    [window display];
}

/*
 *----------------------------------------------------------------------
 *
 * TkpRedrawWidget --
 *
6267
6268
6269
6270
6271
6272
6273
6274
6275

6276
6277
6278
6279
6280
6281
6282
6309
6310
6311
6312
6313
6314
6315


6316
6317
6318
6319
6320
6321
6322
6323







-
-
+







    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];
	[view addTkDirtyRect:bounds];
    }
}


/*
 *----------------------------------------------------------------------
 *
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+




















+

-
+







    wmPtr->hints.initial_state = state;
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    macWin = TkMacOSXGetNSWindowForDrawable(winPtr->window);

    /*
     * Make sure windows are updated before the state change.  As an exception,
     * do not process idle tasks before withdrawing a window.  The purpose of
     * this is to support the common paradigm of immediately withdrawing the
     * root window.  Processing idle tasks before changing the state causes the
     * root to briefly flash on the screen, which users of this paradigm find
     * annoying.  Not processing the events does not guarantee that the window
     * will not appear but makes it more likely.
     */

    if (state != WithdrawnState) {
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {};
    }
    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.
     * Make sure windows are updated after the state change too.
     */

    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){}
}

/*
 *----------------------------------------------------------------------
6583
6584
6585
6586
6587
6588
6589

6590
6591
6592
6593
6594
6595
6596
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652







+








    	TkWmRestackToplevel(winPtr, Above, NULL);
    	if (force) {
    	    [NSApp activateIgnoringOtherApps:YES];
    	}
	if (win && [win canBecomeKeyWindow]) {
	    [win makeKeyAndOrderFront:NSApp];
	    [NSApp setTkEventTarget:TkMacOSXGetTkWindow(win)];
	}
    }

    /*
     * 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,
     * so we can distinguish FocusIn and FocusOut events on either side of the
6675
6676
6677
6678
6679
6680
6681
6682

6683
6684
6685
6686
6687
6688
6689
6731
6732
6733
6734
6735
6736
6737

6738
6739
6740
6741
6742
6743
6744
6745







-
+







    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);
		childWinPtr = (TkWindow *)Tcl_GetHashValue(hPtr);
		*windowPtr++ = childWinPtr;
	    }
	}
	*windowPtr = NULL;
	Tcl_DeleteHashTable(&table);
    }
    return windows;
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6826
6827
6828
6829
6830
6831
6832


6833
6834
6835
6836
6837
6838
6839







-
-







	}
	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);
6858
6859
6860
6861
6862
6863
6864
6865

6866
6867
6868
6869
6870
6871
6872
6912
6913
6914
6915
6916
6917
6918

6919
6920
6921
6922
6923
6924
6925
6926







-
+







		     * 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, *)) {
		    if ([NSApp macOSVersion] >= 101100) {
			NSSize screenSize = [[macWindow screen] frame].size;
			[macWindow setMaxFullScreenContentSize:screenSize];
		    }
		}
	    }
#endif

7000
7001
7002
7003
7004
7005
7006
7007

7008
7009
7010
7011
7012
7013
7014
7054
7055
7056
7057
7058
7059
7060

7061
7062
7063
7064
7065
7066
7067
7068







-
+







		title = winPtr->nameUid;
	    }
	    [macWindow setStyleMask:styleMask];
	    [macWindow setTitle:[NSString stringWithUTF8String:title]];
	    [macWindow setExcludedFromWindowsMenu:NO];
	    wmPtr->flags &= ~WM_TOPMOST;
	}
	if (wmPtr->container != None) {
	if (wmPtr->container != NULL) {
	    TkWindow *containerWinPtr = (TkWindow *)wmPtr->container;

	    if (containerWinPtr && (containerWinPtr->window != None)
		    && TkMacOSXHostToplevelExists(containerWinPtr)) {
		NSWindow *containerMacWin = TkMacOSXGetNSWindowForDrawable(
			containerWinPtr->window);

7174
7175
7176
7177
7178
7179
7180
7181

7182
7183
7184
7185
7186
7187
7188
7228
7229
7230
7231
7232
7233
7234

7235
7236
7237
7238
7239
7240
7241
7242







-
+







    TkWindow *winPtr,		/* Toplevel window to operate on. */
    int *maxWidthPtr,		/* Where to store the current maximum width of
				 * the window. */
    int *maxHeightPtr)		/* Where to store the current maximum height
				 * of the window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    NSRect *maxBounds = (NSRect*)(winPtr->display->screens->ext_data);
    NSRect *maxBounds = (NSRect*)(ScreenOfDisplay(winPtr->display, 0)->ext_data);

    if (wmPtr->maxWidth > 0) {
	*maxWidthPtr = wmPtr->maxWidth;
    } else {
	int maxWidth = maxBounds->size.width - wmPtr->xInParent;

	if (wmPtr->gridWin != NULL) {
Changes to macosx/tkMacOSXWm.h.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
1
2
3
4
5


6
7
8
9
10
11
12
13
14





-
-
+
+







/*
 * 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>
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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
43
44
45
46
47
48
49

50
51
52
53
54
55
56
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57







+







typedef struct Transient {
    TkWindow *winPtr;
    int flags;
    struct Transient *nextPtr;
} Transient;

#define WITHDRAWN_BY_CONTAINER 0x1
#define WITHDRAWN_BY_MASTER 0x1

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
 */

typedef struct TkWmInfo {
Changes to macosx/tkMacOSXXCursors.h.
1
2
3
4
5
6
7
8
9
10



11
12
13
14
15
16
17
1
2
3
4
5
6
7



8
9
10
11
12
13
14
15
16
17







-
-
-
+
+
+







/*
 * tkMacOSXXCursors.h --
 *
 *	This file defines a set of Macintosh cursors that
 *	emulate the X cursor set. All of these cursors were
 *	constructed and donated by Grant Neufeld. (gneufeld@ccs.carleton.ca)
 *
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 * Copyright 2008-2009, Apple Inc.
 * Copyright (c) 2008-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright © 1995-1996 Sun Microsystems, Inc.
 * Copyright © 2008-2009 Apple Inc.
 * Copyright © 2008-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.
 */

static const unsigned char tkMacOSXXCursors[][68] = {

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
1
2
3
4
5
6
7
8




9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27








-
-
-
-
+
+
+
+





+

-
+







/*
 * 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.
 * Copyright © 1995-1997 Sun Microsystems, Inc.
 * Copyright © 2001-2009 Apple Inc.
 * Copyright © 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.
 */

#define XLIB_ILLEGAL_ACCESS
#include "tkMacOSXPrivate.h"
#include "tkMacOSXInt.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
75
76
77
78
79
80
81
82

83
84
85

86
87
88
89
90
91
92
93
94
95
96
97





98
99
100
101
102
103
104
76
77
78
79
80
81
82

83
84
85

86
87
88
89
90
91
92
93





94
95
96
97
98
99
100
101
102
103
104
105







-
+


-
+







-
-
-
-
-
+
+
+
+
+







TkMacOSXDisplayChanged(
    Display *display)
{
    Screen *screen;
    NSArray *nsScreens;


    if (display == NULL || display->screens == NULL) {
    if (display == NULL || (((_XPrivDisplay)(display))->screens) == NULL) {
	return;
    }
    screen = display->screens;
    screen = (((_XPrivDisplay)(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;
	DefaultDepthOfScreen(screen) = NSBitsPerPixelFromDepth([s depth]);
	WidthOfScreen(screen) = bounds.size.width;
	HeightOfScreen(screen) = bounds.size.height;
	WidthMMOfScreen(screen) = (bounds.size.width * 254 + 360) / 720;
	HeightMMOfScreen(screen) = (bounds.size.height * 254 + 360) / 720;

	for (s in nsScreens) {
	    maxBounds = NSUnionRect(maxBounds, [s visibleFrame]);
	}
	*((NSRect *)screen->ext_data) = maxBounds;
    }
}
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189




190
191
192

193
194
195
196
197
198





199

























































200
201
202
203
204
205
206
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
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 0.0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpOpenDisplay/XkbOpenDisplay --
 * 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;
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    int fd = 0;
    static NSRect maxBounds = {{0, 0}, {0, 0}};
    static char vendor[25] = "";
    NSArray *cgVers;

    if (gMacDisplay != NULL) {
	if (strcmp(gMacDisplay->display->display_name, display_name) == 0) {
	if (strcmp(DisplayString(gMacDisplay->display), display_name) == 0) {
	    return gMacDisplay;
	} else {
	    return NULL;
	}
    }

    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    display = (Display *)ckalloc(sizeof(Display));
    screen = (Screen *)ckalloc(sizeof(Screen));
    bzero(display, sizeof(Display));
    bzero(screen, sizeof(Screen));
    display = XkbOpenDisplay((char *)display_name, NULL, NULL, NULL, NULL, NULL);

    display->resource_alloc = MacXIdAlloc;
    LastKnownRequestProcessed(display) = 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_MAX_ALLOWED < 101000
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = (int)systemVersion.majorVersion;
	minor = (int)systemVersion.minorVersion;
	patch = (int)systemVersion.patchVersion;
#endif
	display->release = major << 16 | minor << 8 | patch;
    }

    /*
     * These screen bits never change
     */
    RootWindowOfScreen(screen)	= ROOT_ID;
    DisplayOfScreen(screen)	= display;
    BlackPixelOfScreen(screen) = 0x00000000;
    WhitePixelOfScreen(screen) = 0x00FFFFFF;
    screen->ext_data	= (XExtData *) &maxBounds;

    DefaultVisualOfScreen(screen) = (Visual *)ckalloc(sizeof(Visual));
    DefaultVisualOfScreen(screen)->visualid     = 0;
    DefaultVisualOfScreen(screen)->c_class      = TrueColor;
    DefaultVisualOfScreen(screen)->red_mask     = 0x00FF0000;
    DefaultVisualOfScreen(screen)->green_mask   = 0x0000FF00;
    DefaultVisualOfScreen(screen)->blue_mask    = 0x000000FF;
    DefaultVisualOfScreen(screen)->bits_per_rgb = 24;
    DefaultVisualOfScreen(screen)->map_entries  = 256;

    /*
     * Initialize screen bits that may change
     */

    TkMacOSXDisplayChanged(display);

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
284
285
286
287
288
289
290






















































































291
292
293
294
295
296
297







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    /*
     * 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 --
 *
 *	Deallocates a display structure created by TkpOpenDisplay.
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341


342
343
344
345
346
347
348
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
TkpCloseDisplay(
    TkDisplay *displayPtr)
{
    Display *display = displayPtr->display;
    _XPrivDisplay display = (_XPrivDisplay)displayPtr->display;

    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);
	if (DefaultVisualOfScreen(ScreenOfDisplay(display, 0)) != NULL) {
	    ckfree(DefaultVisualOfScreen(ScreenOfDisplay(display, 0)));
	}
	ckfree(display->screens);
    }
    ckfree(display);
}

/*
451
452
453
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
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

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







-
+















-
+

















-
+







}

char *
XGetAtomName(
    Display *display,
    TCL_UNUSED(Atom))
{
    display->request++;
    LastKnownRequestProcessed(display)++;
    return NULL;
}

XErrorHandler
XSetErrorHandler(
    TCL_UNUSED(XErrorHandler))
{
    return DefaultErrorHandler;
}

Window
XRootWindow(
    Display *display,
    TCL_UNUSED(int))
{
    display->request++;
    LastKnownRequestProcessed(display)++;
    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++;
    LastKnownRequestProcessed(display)++;
    *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;
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
520
521
522
523
524
525
526
























527
528
529
530
531
532
533







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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
     */
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
551
552
553
554
555
556
557

























558
559
560
561
562
563
564







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







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),
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
585
586
587
588
589
590
591
























































































592
593
594
595
596
597
598







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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),
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
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_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++;
    LastKnownRequestProcessed(display)++;
    *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++;
    LastKnownRequestProcessed(display)++;
    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++;
    LastKnownRequestProcessed(display)++;
    return Success;
}

int
XSetClipRectangles(
    Display *d,
    GC gc,

void
Tk_FreeXId(
    TCL_UNUSED(Display *),
    TCL_UNUSED(XID))
    int clip_x_origin,
    int clip_y_origin,
    XRectangle* rectangles,
    int n,
    TCL_UNUSED(int))
{
    /* no-op function needed for stubs implementation. */
}

int
XSync(
    Display *display,
    TCL_UNUSED(Bool))
{
    TkRegion clipRgn = TkCreateRegion();

    /*
     *  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.  On X11 the
     *  call to XSync might cause the window manager to generate more events
     *  which would then get processed. Apparently this process stabilizes on
     *  X11, leaving the window manager in a state where all events have been
     *  generated and no additional events can be genereated by updating widgets.
     *
    while (n--) {
    	XRectangle rect = *rectangles;
     *  It is not clear what the Aqua port should do when XSync is called, but
     *  currently the best option seems to be to do nothing.  (See ticket
     *  [da5f2266df].)
     */

    	rect.x += clip_x_origin;
    	rect.y += clip_y_origin;
    	TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
    	rectangles++;
    }
    LastKnownRequestProcessed(display)++;
    return 0;
}
    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
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
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







-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-







+





-
+



+







-
-
-
-
-
-
-
-
+




-
+



+







+









-
+







XIC
XCreateIC(TCL_UNUSED(XIM), ...)
{
    Debugger();
    return (XIC) 0;
}

int
XDeleteProperty(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Atom))
{
    return Success;
}

#undef XVisualIDFromVisual
int
XGetInputFocus(
    Display *display,
    TCL_UNUSED(Window *),
    TCL_UNUSED(int *))
{
    display->request++;
    return Success;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
    return visual->visualid;
}

#undef XSynchronize
XAfterFunction
XSynchronize(
    Display *display,
    TCL_UNUSED(Bool))
{
    display->request++;
    LastKnownRequestProcessed(display)++;
    return NULL;
}

#undef XUngrabServer
int
XUngrabServer(
    TCL_UNUSED(Display *))
{
    return 0;
}

int
XFreeCursor(
    TCL_UNUSED(Display *),
    TCL_UNUSED(Cursor))
{
    return Success;
}

#undef XNoOp
int
XNoOp(
    Display *display)
{
	display->request++;
    LastKnownRequestProcessed(display)++;
    return 0;
}

#undef XGrabServer
int
XGrabServer(
    TCL_UNUSED(Display *))
{
    return 0;
}

#undef XFree
int
XFree(
    void *data)
{
	if ((data) != NULL) {
		ckfree(data);
	}
    return 0;
}

#undef XFlush
int
XFlush(
    TCL_UNUSED(Display *))
{
    return 0;
}

Changes to macosx/ttkMacOSXTheme.c.
1
2
3
4
5
6
7
8
9
10
11






12
13
14
15
16
17
18
1
2
3
4
5






6
7
8
9
10
11
12
13
14
15
16
17
18





-
-
-
-
-
-
+
+
+
+
+
+







/*
 * 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
 * Copyright © 2004 Joe English
 * Copyright © 2005 Neil Madden
 * Copyright © 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/
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63



64

65
66
67
68
69
70
71
72
73
74
75
76
77






78
79
80
81
82
83
84
27
28
29
30
31
32
33

34
35
36
37
38




39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95







-





-
-
-
-
+
+
+
+
+
+
+




















+
+
+
-
+













+
+
+
+
+
+







 *
 *      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 \
#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] = {
    90.0 / 255, 86.0 / 255, 95.0 / 255, 1.0
};
static CGFloat darkPressedButtonFace[4] = {
    112.0 / 255, 113.0 / 255, 115.0 / 255, 1.0
    114.0 / 255, 110.0 / 255, 118.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 darkSelectedTab[4] = {
    97.0 / 255, 94.0 / 255, 102.0 / 255, 1.0
};
static CGFloat darkTab[4] = {
    44.0 / 255, 41.0 / 255, 50.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] = {
116
117
118
119
120
121
122
123

124
125

126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
127
128
129
130
131
132
133

134
135

136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+

-
+












-
+







 * 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
#define CGCOLOR(nscolor) (nscolor).CGColor
#else
#define CGCOLOR(nscolor) (0 ? (CGColorRef) nscolor : NULL)
#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) { \
    if ((radius) > (bounds).size.width / 2 || (radius) > (bounds).size.height / 2) { \
        return;                                                              \
    }

/*----------------------------------------------------------------------
 * +++ Utilities.
 */

221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+







 *
 * 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
 * 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] = {
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342







-
+







    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);
    y = bounds.origin.y + trunc(bounds.size.height / 2) + 1;
    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);
714
715
716
717
718
719
720

721

722






723
724
725
726
727
728
729
725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747







+
-
+

+
+
+
+
+
+








    /*
     * Fill the button face with the appropriate color.
     */

    bounds = CGRectInset(bounds, 1, 1);
    if (kind == kThemePushButton && (state & TTK_STATE_PRESSED)) {
	if ([NSApp macOSVersion] < 120000) {
	GradientFillRoundedRectangle(context, bounds, 4,
	    GradientFillRoundedRectangle(context, bounds, 4,
	    pressedPushButtonGradient, 2);
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkPressedButtonFace
		count: 4];
	    SolidFillRoundedRectangle(context, bounds, 4, faceColor);
	}
    } else if (kind == kThemePushButton &&
	       (state & TTK_STATE_ALTERNATE) &&
	       !(state & TTK_STATE_BACKGROUND)) {
	GradientFillRoundedRectangle(context, bounds, 4,
	    darkSelectedGradient, 2);
    } else {
	if (state & TTK_STATE_DISABLED) {
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
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







+









+
-
-
-
-
+
+
+
+
-
-
-
+
+
+











+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    CGRect bounds,
    Ttk_State state,
    CGContextRef context)
{
    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
    NSColor *faceColor, *stroke;
    CGRect originalBounds = bounds;
    int OSVersion = [NSApp macOSVersion];

    CGContextSetLineWidth(context, 1.0);
    CGContextClipToRect(context, bounds);

    /*
     * Extend the bounds to one or both sides so the rounded part will be
     * clipped off.
     */

    if (OSVersion < 110000 || !(state & TTK_STATE_SELECTED)) {
    if (!(state & TTK_STATE_FIRST_TAB)) {
	bounds.origin.x -= 10;
	bounds.size.width += 10;
    }
	if (!(state & TTK_STATE_FIRST_TAB)) {
	    bounds.origin.x -= 10;
	    bounds.size.width += 10;
	}

    if (!(state & TTK_STATE_LAST_TAB)) {
	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) {
	    if (OSVersion < 110000) {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkDisabledButtonFace
		count: 4];
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkButtonFace
		count: 4];
		faceColor = [NSColor colorWithColorSpace: deviceRGB
					      components: darkDisabledButtonFace
						   count: 4];
	    } else {
		faceColor = [NSColor colorWithColorSpace: deviceRGB
					      components: darkTab
						   count: 4];
	    }
	} else {
	    if (OSVersion < 110000) {
		faceColor = [NSColor colorWithColorSpace: deviceRGB
					      components: darkButtonFace
						   count: 4];
	    } else {
		faceColor = [NSColor colorWithColorSpace: deviceRGB
					      components: darkTab
						   count: 4];
	    }
	}
	SolidFillRoundedRectangle(context, bounds, 4, faceColor);

        /*
         * Draw a separator line on the left side of the tab if it
         * not first.
         */
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
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







-
-
-
-
-
+
+
+
+
+





+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    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.)
         */
	/*
	 * This is the selected tab; paint it with the current accent color.
	 * 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)) {
	    if (OSVersion < 110000) {
	    GradientFillRoundedRectangle(context, bounds, 4,
		darkSelectedGradient, 2);
	} else {
	    faceColor = [NSColor colorWithColorSpace: deviceRGB
		components: darkInactiveSelectedTab
		count: 4];
		GradientFillRoundedRectangle(context, bounds, 4,
					     darkSelectedGradient, 2);
	    } else {
		faceColor = [NSColor colorWithColorSpace: deviceRGB
					      components: darkSelectedTab
						   count: 4];
		SolidFillRoundedRectangle(context, bounds, 4, faceColor);
	    }
	} else {
	    if (OSVersion < 110000) {
		faceColor = [NSColor colorWithColorSpace: deviceRGB
					      components: darkInactiveSelectedTab
						   count: 4];
	    } else {
		faceColor = [NSColor colorWithColorSpace: deviceRGB
					      components: darkSelectedTab
						   count: 4];
	    }
	    SolidFillRoundedRectangle(context, bounds, 4, faceColor);
	}
	HighlightButtonBorder(context, bounds);
    }
}

/*----------------------------------------------------------------------
1139
1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151
1152
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198







+







    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);
    CGPathRelease(path);
    CGContextAddRect(context, bounds);
    CGContextEOFillPath(context);
    CGContextRestoreGState(context);
}
/*----------------------------------------------------------------------
 * +++ DrawDarkFrame --
 *
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
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







-
-

-
+
-




-
+










-
+











-
+





-
+






-
+
-








/*----------------------------------------------------------------------
 * +++ Button elements.
 */

static void ButtonElementMinSize(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    int *minWidth,
    int *minHeight,
    int *minHeight)
    TCL_UNUSED(Ttk_Padding *))
{
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;

    if (params->heightMetric != NoThemeMetric) {
	ChkErr(GetThemeMetric, params->heightMetric, minHeight);
	ChkErr(GetThemeMetric, params->heightMetric, (SInt *) 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
         * For buttons with labels the minwidth must be 0 to force 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,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ThemeButtonParams *params = clientData;
    ThemeButtonParams *params = (ThemeButtonParams *)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,
    ButtonElementMinSize(clientData, minWidth, minHeight);
	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
1416
1417
1418
1419
1420
1421
1422
1423

1424
1425
1426
1427
1428
1429

1430
1431
1432
1433
1434
1435
1436
1458
1459
1460
1461
1462
1463
1464

1465
1466
1467
1468
1469
1470

1471
1472
1473
1474
1475
1476
1477
1478







-
+





-
+







	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 *),
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = clientData;
    ThemeButtonParams *params = (ThemeButtonParams *)clientData;
    CGRect bounds = BoxToRect(d, b);
    HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, state, tkwin);

    bounds = NormalizeButtonBounds(params->heightMetric, bounds);

    BEGIN_DRAWING(d)
    if (TkMacOSXInDarkMode(tkwin)) {
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
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







-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-
+

-
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+

-
+

-
-
-
+
+
+







	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.
         */
    /*
     * 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 &&
    if (info.kind == kThemePopupButton &&
	    (state & TTK_STATE_BACKGROUND)) {
	    CGRect innerBounds = CGRectInset(bounds, 1, 1);
	    NSColor *whiteRGBA = [NSColor whiteColor];
	    SolidFillRoundedRectangle(dc.context, innerBounds, 4, whiteRGBA);
	}
	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.
         */
    /*
     * A BevelButton with mixed value is drawn borderless, which does make
     * much sense for us.
     */

	if (info.kind == kThemeRoundedBevelButton &&
    if (info.kind == kThemeRoundedBevelButton &&
	    info.value == kThemeButtonMixed) {
	    info.value = kThemeButtonOff;
	    info.state = kThemeStateInactive;
	}
	info.value = kThemeButtonOff;
	info.state = kThemeStateInactive;
    }
	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);
    }
    END_DRAWING
}

static Ttk_ElementSpec ButtonElementSpec = {
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
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







-
-
-
-
+
+
+
+









-
-
+
+







 *
 * <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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);
    HIThemeTabDrawInfo info = {
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
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







-
-
-
-
-
+
+
+
+
+






-
-
+
+







};

/*
 * Notebook panes:
 */

static void PaneElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_MakePadding(9, 5, 9, 9);
}

static void PaneElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

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
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







-
-
-
-
-
+
+
+
+
+






-
-
+
+







 * 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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(4);
}

static void GroupElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

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
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







-
+

-
+




-
-
-
-
-
+
+
+
+
+













-
+







    Tcl_Obj     *fieldbackgroundObj;
} EntryElement;

#define ENTRY_DEFAULT_BACKGROUND "systemTextBackgroundColor"

static Ttk_ElementOptionSpec EntryElementOptions[] = {
    {"-background", TK_OPTION_BORDER,
     offsetof(EntryElement, backgroundObj), ENTRY_DEFAULT_BACKGROUND},
     Tk_Offset(EntryElement, backgroundObj), ENTRY_DEFAULT_BACKGROUND},
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(EntryElement, fieldbackgroundObj), ENTRY_DEFAULT_BACKGROUND},
     Tk_Offset(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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    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;
    EntryElement *e = (EntryElement *)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)) {
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
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







-
+
+


-
-
-
+
+
+






+
+
+
-
+
+



-
-
+
+















-

-
+
+
+
+

+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+







 *      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 Ttk_Padding ComboboxPadding = {4, 4, 20, 4};
static Ttk_Padding DarkComboboxPadding = {6, 6, 22, 6};

static void ComboboxElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    *minWidth = 24;
    *minHeight = 23;
    if (TkMacOSXInDarkMode(tkwin)) {
	*paddingPtr = DarkComboboxPadding;
    } else {
    *paddingPtr = ComboboxPadding;
	*paddingPtr = ComboboxPadding;
    }
}

static void ComboboxElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    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;
	bounds = CGRectInset(bounds, 3, 3);
	if (state & TTK_STATE_FOCUS) {
	    DrawDarkFocusRing(bounds, dc.context);
	}
	DrawDarkButton(bounds, info.kind, state, dc.context);
    } else {
    } 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);
	if ([NSApp macOSVersion] > 100800) {
	    if ((state & TTK_STATE_BACKGROUND) &&
		!(state & TTK_STATE_DISABLED)) {
		NSColor *background = [NSColor textBackgroundColor];
		CGRect innerBounds = CGRectInset(bounds, 1, 4);
		bounds.origin.y += 1;
		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,
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
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







-
-
-
-
+
+
+
+


-
+










-
-
+
+







 *      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),
static void SpinButtonElementSize(
    TCL_UNUSED(void *),       /* clientdata */
    TCL_UNUSED(void *),       /* elementRecord */
    TCL_UNUSED(Tk_Window),    /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* PaddingPtr */
{
    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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, SpinbuttonMargins));
    int infoState;
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
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







-
+


-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-

-
-
+
+









-
+







    END_DRAWING
}

static Ttk_ElementSpec SpinButtonUpElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonUpElementSize,
    SpinButtonElementSize,
    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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    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;
    bounds.size.height += bounds.size.height;
    if (state & TTK_STATE_PRESSED) {
	infoState = kThemeStatePressedDown;
    } else {
	return;
    }
    const HIThemeButtonDrawInfo info = {
	.version = 0,
2061
2062
2063
2064
2065
2066
2067
2068

2069
2070
2071
2072
2073
2074
2075
2098
2099
2100
2101
2102
2103
2104

2105
2106
2107
2108
2109
2110
2111
2112







-
+







    END_DRAWING
}

static Ttk_ElementSpec SpinButtonDownElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinButtonDownElementSize,
    SpinButtonElementSize,
    SpinButtonDownElementDraw
};

/*----------------------------------------------------------------------
 * +++ DrawThemeTrack-based elements --
 *
 *    Progress bars and scales. (See also: <<NOTE-TRACKS>>)
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
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







-
-
-
-
+
+
+
+




-
-
+
+


-
+
















-
-
-
+
+
+



-
+







    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},
    {"-from", TK_OPTION_DOUBLE, Tk_Offset(TrackElement, fromObj), NULL},
    {"-to", TK_OPTION_DOUBLE, Tk_Offset(TrackElement, toObj), NULL},
    {"-value", TK_OPTION_DOUBLE, Tk_Offset(TrackElement, valueObj), NULL},
    {"-orient", TK_OPTION_STRING, Tk_Offset(TrackElement, orientObj), NULL},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TrackElementSize(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(void *),       /* elementRecord */
    TCL_UNUSED(Tk_Window),    /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    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;
    TrackElementData *data = (TrackElementData *)clientData;
    TrackElement *elem = (TrackElement *)elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;
    double from = 0, to = 100, value = 0, factor;
    CGRect bounds;

    TtkGetOrientFromObj(NULL, elem->orientObj, &orientation);
    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);

    /*
     * HIThemeTrackDrawInfo uses 2-byte alignment; assigning to a separate
2158
2159
2160
2161
2162
2163
2164
2165

2166
2167
2168
2169
2170
2171
2172
2195
2196
2197
2198
2199
2200
2201

2202
2203
2204
2205
2206
2207
2208
2209







-
+







	.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,
	.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;
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215



2216
2217
2218

2219
2220
2221
2222
2223
2224
2225
2243
2244
2245
2246
2247
2248
2249



2250
2251
2252
2253
2254

2255
2256
2257
2258
2259
2260
2261
2262







-
-
-
+
+
+


-
+







 * 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),
    TCL_UNUSED(void *),        /* clientData */
    TCL_UNUSED(void *),        /* elementRecord */
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    *minWidth = *minHeight = 24;
}

static Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
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
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







-
+

-
+

-
+

-
+

-
+



-
-
-
+
+
+


-
+















-
-
-
-
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+









-
+
-
-
-


-
-
+
+

-
+
-

-
+

-







    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"},
     Tk_Offset(PbarElement, orientObj), "horizontal"},
    {"-value", TK_OPTION_DOUBLE,
     offsetof(PbarElement, valueObj), "0"},
     Tk_Offset(PbarElement, valueObj), "0"},
    {"-maximum", TK_OPTION_DOUBLE,
     offsetof(PbarElement, maximumObj), "100"},
     Tk_Offset(PbarElement, maximumObj), "100"},
    {"-phase", TK_OPTION_INT,
     offsetof(PbarElement, phaseObj), "0"},
     Tk_Offset(PbarElement, phaseObj), "0"},
    {"-mode", TK_OPTION_STRING,
     offsetof(PbarElement, modeObj), "determinate"},
     Tk_Offset(PbarElement, modeObj), "determinate"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void PbarElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(void *),        /* clientData */
    TCL_UNUSED(void *),        /* elementRecord */
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    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;
    PbarElement *pbar = (PbarElement *)elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL, phase = 0, kind;

    /*
     * Using 1000 as the maximum should give better than 1 pixel
     * resolution for most progress bars.
     */

    int ivalue, imaximum = 1000;
    CGRect bounds;

    TtkGetOrientFromObj(NULL, pbar->orientObj, &orientation);
    Tcl_GetDoubleFromObj(NULL, pbar->valueObj, &value);
    Tcl_GetDoubleFromObj(NULL, pbar->maximumObj, &maximum);
    Ttk_GetOrientFromObj(NULL, pbar->orientObj, &orientation);
    kind = !strcmp("indeterminate", Tcl_GetString(pbar->modeObj)) ?
	kThemeIndeterminateBar : kThemeProgressBar;
    if (kind == kThemeIndeterminateBar) {
	Tcl_GetIntFromObj(NULL, pbar->phaseObj, &phase);

	/*
	 * On macOS 11 the fraction of an indeterminate progress bar which is
	 * traversed by the oscillating thumb is value / maximum.  The phase
	 * determines the position of the moving thumb in that range and is
	 * apparently expected to vary between 0 and 120.  On earlier systems
	 * it is unclear how the phase is used in generating the animation.
	 */

	ivalue = imaximum;
    } else {
	double value, maximum;
	Tcl_GetDoubleFromObj(NULL, pbar->valueObj, &value);
	Tcl_GetDoubleFromObj(NULL, pbar->maximumObj, &maximum);
    Tcl_GetIntFromObj(NULL, pbar->phaseObj, &phase);
    factor = RangeToFactor(maximum);
	ivalue = (value / maximum)*1000;
    }

    /*
     * 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 =
	.kind = kind,
	    (!strcmp("indeterminate",
	    Tcl_GetString(pbar->modeObj)) && value) ?
	    kThemeIndeterminateBar : kThemeProgressBar,
	.bounds = bounds,
	.min = 0,
	.max = maximum * factor,
	.value = value * factor,
	.max = imaximum,
	.value = ivalue,
	.attributes = kThemeTrackShowThumb |
	    (orientation == TTK_ORIENT_HORIZONTAL ?
	    (orientation == TTK_ORIENT_HORIZONTAL ? kThemeTrackHorizontal : 0),
	    kThemeTrackHorizontal : 0),
	.enableState = Ttk_StateTableLookup(ThemeTrackEnableTable, state),
	.trackInfo.progress.phase = phase,
	.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];
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
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







-
+



-
+

-
+




-
-
+
+


-
+







typedef struct
{
    Tcl_Obj *orientObj;
} ScrollbarElement;

static Ttk_ElementOptionSpec ScrollbarElementOptions[] = {
    {"-orient", TK_OPTION_STRING,
     offsetof(ScrollbarElement, orientObj), "horizontal"},
     Tk_Offset(ScrollbarElement, orientObj), "horizontal"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};
static void TroughElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),    /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
    int *minHeight,
    Ttk_Padding *paddingPtr)
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;
    SInt32 thickness = 15;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    Ttk_GetOrientFromObj(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 {
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
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







-
+




-
+

-
-
+
+





-
+







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 *),
    TCL_UNUSED(void *),    /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
    TCL_UNUSED(Ttk_State)) /* state */
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    int 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);
    Ttk_GetOrientFromObj(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
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
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







-
+

-
+


-
+

-
-
+
+

-
+










-
+






-
-
+
+

-
+







    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    TroughElementSize,
    TroughElementDraw
};
static void ThumbElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),        /* clientData */
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    Ttk_GetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    if (orientation == TTK_ORIENT_VERTICAL) {
	*minHeight = 18;
	*minWidth = 8;
    } else {
	*minHeight = 8;
	*minWidth = 18;
    }
}

static void ThumbElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),        /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ScrollbarElement *scrollbar = elementRecord;
    Ttk_Orient orientation = TTK_ORIENT_HORIZONTAL;
    ScrollbarElement *scrollbar = (ScrollbarElement *)elementRecord;
    int orientation = TTK_ORIENT_HORIZONTAL;

    TtkGetOrientFromObj(NULL, scrollbar->orientObj, &orientation);
    Ttk_GetOrientFromObj(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
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579



2580
2581
2582

2583
2584
2585
2586
2587
2588
2589
2623
2624
2625
2626
2627
2628
2629



2630
2631
2632
2633
2634

2635
2636
2637
2638
2639
2640
2641
2642







-
-
-
+
+
+


-
+







    TK_STYLE_VERSION_2,
    sizeof(ScrollbarElement),
    ScrollbarElementOptions,
    ThumbElementSize,
    ThumbElementDraw
};
static void ArrowElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(void *),        /* clientData */
    TCL_UNUSED(void *),        /* elementRecord */
    TCL_UNUSED(Tk_Window),     /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    if ([NSApp macOSVersion] < 100800) {
	*minHeight = *minWidth = 14;
    } else {
	*minHeight = *minWidth = -1;
    }
}
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
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







-
-
-
+
+
+


-
+





-
-
+
+







 *
 *    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),
    TCL_UNUSED(void *),       /* clientData */
    TCL_UNUSED(void *),       /* elementRecord */
    TCL_UNUSED(Tk_Window),    /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    *minWidth = *minHeight = 1;
}

static void SeparatorElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),       /* clientData */
    TCL_UNUSED(void *),       /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    const HIThemeSeparatorDrawInfo info = {
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
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







-
-
-
+
+
+


-
+
















-
-
-
+
+
+







 * +++ Size grip elements -- (obsolete)
 */

static const ThemeGrowDirection sizegripGrowDirection
    = kThemeGrowRight | kThemeGrowDown;

static void SizegripElementSize(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    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),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    Drawable d,
    Ttk_Box b,
    unsigned int state)
{
    CGRect bounds = BoxToRect(d, b);
    HIThemeGrowBoxDrawInfo info = {
	.version = 0,
2752
2753
2754
2755
2756
2757
2758
2759
2760


2761
2762
2763
2764
2765
2766
2767
2805
2806
2807
2808
2809
2810
2811


2812
2813
2814
2815
2816
2817
2818
2819
2820







-
-
+
+







 *      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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    CGRect bounds = BoxToRect(d, b);

2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2832
2833
2834
2835
2836
2837
2838

2839
2840
2841
2842
2843
2844
2845







-







	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,
2827
2828
2829
2830
2831
2832
2833
2834
2835


2836
2837
2838
2839
2840
2841
2842
2879
2880
2881
2882
2883
2884
2885


2886
2887
2888
2889
2890
2891
2892
2893
2894







-
-
+
+







 *    <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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    TCL_UNUSED(Ttk_Box),
    TCL_UNUSED(Ttk_State))
{
    ThemeBrush brush = kThemeBrushToolbarBackground;
    CGRect bounds = BoxToRect(d, Ttk_WinBox(tkwin));
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
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







-
+








-
+




-
+






-
+



















-
+







    ToolbarBackgroundElementDraw
};

/*----------------------------------------------------------------------
 * +++ Field elements --
 *
 *      Used for the Treeview widget. This is like the BackgroundElement
 *      except that the fieldbackground color is configureable.
 *      except that the fieldbackground color is configurable.
 */

typedef struct {
    Tcl_Obj     *backgroundObj;
} FieldElement;

static Ttk_ElementOptionSpec FieldElementOptions[] = {
    {"-fieldbackground", TK_OPTION_BORDER,
     offsetof(FieldElement, backgroundObj), "white"},
     Tk_Offset(FieldElement, backgroundObj), "white"},
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void FieldElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),    /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_State))
{
    FieldElement *e = elementRecord;
    FieldElement *e = (FieldElement *)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
 *    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},
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931





2932
2933
2934
2935
2936
2937
2938
2972
2973
2974
2975
2976
2977
2978





2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990







-
-
-
-
-
+
+
+
+
+







    {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 *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    TCL_UNUSED(int *),     /* minWidth */
    TCL_UNUSED(int *),     /* minHeight */
    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.
     */
2963
2964
2965
2966
2967
2968
2969
2970

2971
2972
2973
2974
2975
2976

2977
2978
2979
2980
2981
2982
2983
3015
3016
3017
3018
3019
3020
3021

3022
3023
3024
3025
3026
3027

3028
3029
3030
3031
3032
3033
3034
3035







-
+





-
+







	ButtonElementSize(clientData, elementRecord, tkwin, minWidth,
	    minHeight, paddingPtr);
    }
}

static void TreeHeaderElementDraw(
    void *clientData,
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ThemeButtonParams *params = clientData;
    ThemeButtonParams *params = (ThemeButtonParams *)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),
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
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







-
-
-
+
+
+


-
+










-
-
+
+







#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),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
    int *minHeight,
    TCL_UNUSED(Ttk_Padding *))
    TCL_UNUSED(Ttk_Padding *)) /* paddingPtr */
{
    SInt32 s;

    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleWidth, &s);
    *minWidth = s;
    ChkErr(GetThemeMetric, kThemeMetricDisclosureTriangleHeight, &s);
    *minHeight = s;
}

static void DisclosureElementDraw(
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    if (!(state & TTK_TREEVIEW_STATE_LEAF)) {
	int triangleState = TkMacOSXInDarkMode(tkwin) ?
3277
3278
3279
3280
3281
3282
3283
3284
3285


3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3329
3330
3331
3332
3333
3334
3335


3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350







-
-
+
+














    Ttk_RegisterLayouts(themePtr, LayoutTable);

    Tcl_PkgProvide(interp, "ttk::theme::aqua", TTK_VERSION);
    return TCL_OK;
}

MODULE_SCOPE
int Ttk_MacOSXPlatformInit(
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/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
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72







-
+









-
+







.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> {
.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 <Leave> {.t.c itemconf current -fill $prevFill -outline $prevOutline}
.t.c bind arc <Any-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
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99







-
+







}

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"}
bind .t.c <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
}
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
1
2
3


4
5
6
7
8
9
10
11
12
13
14

15
16
17
18

19
20
21
22

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 © 1994 The Regents of the University of California.
# Copyright © 1998-2000 by Scriptics Corporation.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1998-2000 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}
} -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}
} -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"}
} -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?"}
} -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?
} -returnCodes {ok} -result {}  ;#keep -result {} and -returnCodes {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?"}
} -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
Changes to tests/bgerror.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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
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 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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] {
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50







-
+








# 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
controlPointerWarpTiming
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
429
430
431
432
433
434
435
436
437


438
439
440
441
442
443
444



445
446
447
448
449
450
451
452

453
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
426
427
428
429
430
431
432


433
434
435
436
437
438



439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
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







-
-
+
+




-
-
-
+
+
+







-
+












-
+

















-
+













-
+







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 <Key> {lappend x "%W %K Test KeyPress"}
    bind all <Key> {lappend x "%W %K all KeyPress"}
    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>
    event generate .t.f <Key-colon>
    event generate .t.f <Key-plus>
    event generate .t.f <Key-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 _}}
} -result {{.t.f colon .t.f :} {.t.f colon Test :} {.t.f colon all KeyPress} {.t.f plus Test KeyPress} {.t.f plus all KeyPress} {.t.f underscore Test KeyPress} {.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>
    event generate .t.f <Key-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>
    event generate .t.f <Key-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>
        event generate .t.f <Key-colon>
    }
    frame .t.f -class Test -width 150 -height 100
    pack .t.f
    focus -force .t.f
    update
    set x {}
} -body {
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
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







-
+
















-
+







    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>
    event generate .t.f <Key-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>
    event generate .t.f <Key-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)}}

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
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







-
+















-
+







    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 {
test bind-13.10 {Tk_BindEvent procedure: don't ignore NotifyInferior - bug 47d4f29159} -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}
} -result {Enter100 Enter101 Leave102 Leave103}
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 {
615
616
617
618
619
620
621
622

623
624

625
626
627
628
629
630
631
612
613
614
615
616
617
618

619
620

621
622
623
624
625
626
627
628







-
+

-
+







    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 <Key-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 <Key-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
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
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







+
















+







    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
    update idletasks
    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
    update idletasks
    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>
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
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







-
+
















-
+















-
-
-
+
+
+












-
+












-
+












-
+
















-
-
-
+
+
+












-
-
+
+







    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 <Key-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 <Key-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>
    event generate .t.f <Key-a>
    event generate .t.f <Key-c>
    event generate .t.f <Key-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
    event generate .t.f <Key-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
    event generate .t.f <Key-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
    event generate .t.f <Key-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
    event generate .t.f <Key-a>
    event generate .t.f <Key-Shift_L>
    event generate .t.f <Key-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>
    event generate .t.f <Key-a>
    event generate .t.f <Key-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
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
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







+














+














+







    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
    update idletasks
    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
    update idletasks
    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
    update idletasks
    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
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
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







-
+













-
+







    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
    event generate .t.f <Key-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
    event generate .t.f <Key-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
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
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







-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+



-
+







    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>
    event generate .t.f <Key-a>
    event generate .t.f <Key-A> -state 1
    event generate .t.f <Key-Tab>
    event generate .t.f <Key-Return>
    event generate .t.f <Key-F1>
    event generate .t.f <Key-Shift_L>
    event generate .t.f <Key-space>
    event generate .t.f <Key-dollar> -state 1
    event generate .t.f <Key-braceleft> -state 1
    event generate .t.f <Key-Multi_key>
    event generate .t.f <Key-e>
    event generate .t.f <Key-apostrophe>
    set x
} -cleanup {
    destroy .t.f
} -result {a A {	} {\r} {{}} {{}} { } {\$} \\\{ {{}} {{}} \xE9}
} -result {a A {	} {\r} {{}} {{}} { } {\$} \\\{ {{}} {{}} \u00e9}
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"}
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
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







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+












-
+












-
+







    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
    event generate .t.f <Key-a>
    event generate .t.f <Key-A> -state 1
    event generate .t.f <Key-Tab>
    event generate .t.f <Key-F1>
    event generate .t.f <Key-Shift_L>
    event generate .t.f <Key-space>
    event generate .t.f <Key-dollar> -state 1
    event generate .t.f <Key-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>
    event generate .t.f <Key-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
    event generate .t.f <Key-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
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
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







-
+




















-
+







    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>
    event gen .t.e <Key-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>
    event gen .t.e <Key-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}
2235
2236
2237
2238
2239
2240
2241
2242

2243
2244
2245
2246
2247
2248
2249
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246
2247
2248
2249
2250
2251







-
+







} -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>}
} -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>}
2348
2349
2350
2351
2352
2353
2354
2355

2356
2357
2358
2359
2360
2361
2362
2363

2364
2365
2366
2367
2368
2369
2370
2350
2351
2352
2353
2354
2355
2356

2357
2358
2359
2360
2361
2362
2363
2364

2365
2366
2367
2368
2369
2370
2371
2372







-
+







-
+







} -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>}
} -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>}
} -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>>
2405
2406
2407
2408
2409
2410
2411
2412

2413
2414
2415
2416
2417
2418
2419
2407
2408
2409
2410
2411
2412
2413

2414
2415
2416
2417
2418
2419
2420
2421







-
+







} -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>}
} -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 {
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
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







-
+



-
+




















-
+





-
+







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 add <<xyz>> <Control-Key-v>
    event info <<xyz>>
} -cleanup {
    event delete <<xyz>>
} -result {<Control-Key-v>}
} -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>>}
} -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>
    event add <<def>> <Key-F6>
    lsort [event info]
} -cleanup {
    event delete <<xyz>>
    event delete <<abc>>
    event delete <<def>>
} -result {<<abc>> <<def>> <<xyz>>}

2783
2784
2785
2786
2787
2788
2789
2790

2791
2792
2793
2794
2795
2796
2797
2785
2786
2787
2788
2789
2790
2791

2792
2793
2794
2795
2796
2797
2798
2799







-
+







    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>
    event generate .t.f <Control-Key-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
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
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







-
+



















-
+







} -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
    bind .b <Meta-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>>}
} -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}
5189
5190
5191
5192
5193
5194
5195
5196

5197
5198
5199
5200
5201
5202
5203
5191
5192
5193
5194
5195
5196
5197

5198
5199
5200
5201
5202
5203
5204
5205







-
+







} -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 <Meta-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
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
5440
5441
5442
5443
5444
5445
5446




































5447
5448
5449
5450
5451
5452
5453







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







} -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
5540
5541
5542
5543
5544
5545
5546
5547

5548
5549
5550
5551
5552
5553

5554
5555
5556
5557
5558
5559
5560
5506
5507
5508
5509
5510
5511
5512

5513
5514
5515
5516
5517
5518

5519
5520
5521
5522
5523
5524
5525
5526







-
+





-
+








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}"
    bind .t.f <Button> "set x {event ButtonPress}"
    set x xyzzy
    event generate .t.f <Button>
    list $x [bind .t.f]
} -cleanup {
    destroy .t.f
} -result {{event Button} <Button>}
} -result {{event ButtonPress} <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 {
5807
5808
5809
5810
5811
5812
5813
5814
5815


5816
5817
5818
5819
5820
5821
5822
5773
5774
5775
5776
5777
5778
5779


5780
5781
5782
5783
5784
5785
5786
5787
5788







-
-
+
+







} -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"}
    bind .t <Button-6> foo
} -returnCodes error -result {bad button number "6"}
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"}
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








-
+















-
-
+
+

-
+










-
-
+
+

-
+










-
-
+
+

-
+










-
-
+
+

-
+










-
-
+
+





-
+






-
+






-
+







    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
    bind .t <Key-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}"
    bind .t.f <Key-colon> "lappend x \"keysym received\""
    bind .t.f <Key-underscore> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <colon> ;# -state 0
    event generate .t.f <Key-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}"
    bind .t.f <Key-Return> "lappend x \"keysym Return\""
    bind .t.f <Key-x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <Return> -state 0
    event generate .t.f <Key-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}"
    bind .t.f <Key-X> "lappend x \"keysym X\""
    bind .t.f <Key-x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <X> -state 1
    event generate .t.f <Key-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}"
    bind .t.f <Key-X> "lappend x \"keysym X\""
    bind .t.f <Key-x> "lappend x {bad binding match}"
    set x [lsort [bind .t.f]]
    event generate .t.f <X> -state 1
    event generate .t.f <Key-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 {
} -result <Key-ETH>
test bind-28.10 {keysym names, Ooblique -> Oslash} -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>}
} -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>}
} -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>}
} -result <Key-Greek_IOTAdieresis>


test bind-29.1 {Tcl_BackgroundError procedure} -setup {
    proc bgerror msg {
        global x errorInfo
        set x [list $msg $errorInfo]
    }
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242

6243
6244
6245
6246
6247
6248
6249
6138
6139
6140
6141
6142
6143
6144


6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158







-
-






+







    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
    controlPointerWarpTiming
    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]
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278




6279
6280
6281
6282
6283
6284
6285
6177
6178
6179
6180
6181
6182
6183




6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194







-
-
-
-
+
+
+
+







} -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>
    bind .t.f <Alt-Control-Key-A> { lappend x "Alt-Control" }
    bind .t.f <Shift-Control-Key-A> { lappend x "Shift-Control" }
    bind .t.f <Shift-Key-A> { lappend x "Shift" }
    event generate .t.f <Alt-Control-Key-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
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
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







-
+









-
-
-
+
+
+


-
-
-
+
+
+







} -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" }
    bind .t.f <Any-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>
    bind .t.f <Key-A> { set x "A" }
    event generate .t.f <Key-A>
    event generate .t.f <Key-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>
    bind .t.f <Key-A> { set x "A" }
    bind .t.f <Double-Key-A> { set x "AA" }
    event generate .t.f <Key-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
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433





6434
6435
6436
6437
6438
6439
6440
6331
6332
6333
6334
6335
6336
6337





6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349







-
-
-
-
-
+
+
+
+
+







} -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>
    bind .t.f <Key-A> { set x "A" }
    bind .t.f <Double-Key-A> { set x "AA" }
    focus -force .t.f; event generate .t.f <Key-A>
    focus -force .t.g; event generate .t.g <Key-A>
    focus -force .t.f; event generate .t.f <Key-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]
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
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







+
+
+
+
-
-
+
+














+
+
+
+
-
+







    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
    # This test case shows that old implementation has an issue, because
    # it is expected that <Double-Button-1> is matching, this binding
    # is more specific. But new implementation will be conform to old,
    # and so "11" is the expected result.
} -result {Double}
test bind-33.3 {prefer most specific event} -setup {
} -result 11
test bind-33.3 {should 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
    # Also this test case shows that old implementation has an issue, it is
    # expected that <a><Double-Button-1><a> is matching, because <Double-Button-1> is more
    # specific than <Button-1><Button-1>. But new implementation will be conform to old,
    # and so "11" is the expected result.
} -result {Double}
} -result 11
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" }
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
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







-
+
















-
+




















+
+
+
+
-
+













-
+






-
-
+
+








-
+















-
+


















-
+







    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}
} -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}
} -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
    # This test case shows that old implementation has an issue, because
    # it is expected that first one is matching, this binding
    # is more specific. But new implementation will be conform to old,
    # and so "last" is the expected result.
} -result {first}
} -result last
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}
} -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" }
    bind .t.f <Button-1><Control-Button-1> { lappend x "first" }
    bind .t.f <Control-Button-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}
} -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}
} -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}
} -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" }
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
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







-
+






-
+

+


-
+

+





-
+











+


+

















+








+

+







} -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
    after 10 ; 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
    after 10 ; update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    controlPointerWarpTiming
    set pointerPos1 [winfo pointerxy .top]
    wm geometry .top +600+600
    update
    after 10 ; update
    event generate .top <Motion> -x 20 -y 20 -warp 1
    controlPointerWarpTiming
    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}]} {
        if {$pos1 != ($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
    controlPointerWarpTiming
    set res [winfo pointerxy .]
    event generate {} <Motion> -x 200 -y 200 -warp 1
    controlPointerWarpTiming
    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
    controlPointerWarpTiming
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
    event generate {} <Motion> -x 100 -y 100 -warp 1
    controlPointerWarpTiming
    event generate {} <Motion> -x -1 -y -1 -warp 1
    controlPointerWarpTiming
    foreach dim [winfo pointerxy .] {
        if {$dim <= $halo} {
            lappend res ok
        } else {
            lappend res $dim
        }
    }
6976
6977
6978
6979
6980
6981
6982
6983
6984


6985
6986
6987
6988
6989
6990
6991
6904
6905
6906
6907
6908
6909
6910


6911
6912
6913
6914
6915
6916
6917
6918
6919







-
-
+
+







} -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]
	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}
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
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







+















+


+


+









+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









    }
    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
    controlPointerWarpTiming
    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
    controlPointerWarpTiming
    foreach {x1 y1} [winfo pointerxy .top.l] {}
    event generate {} <Motion> -warp 1 -x 50 -y 50
    controlPointerWarpTiming
    grab release .top
    event generate .top.l <Motion> -warp 1 -x 10 -y 10
    controlPointerWarpTiming
    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

test bind-37.1 {Promotion tables do not contain duplicate sequences, bug [43573999ca]} -body {
    proc A {} {
       bind .c <B1-Motion><Enter> {}
       set myv(a) 1
       set b [array get myv]
       bind .c <B1-Motion><Enter> "puts Trigger"
    }
    pack [canvas .c]
    bind .c <ButtonRelease-1>  "A"
    A
    update
    event generate .c <Button-1>
    event generate .c <B1-Motion>
    event generate .c <B1-Motion>
    event generate .c <B1-Motion>
    event generate .c <ButtonRelease-1>
    event generate .c <B1-Motion>
} -cleanup {
    destroy .c
} -returnCodes ok -result {}  ; # shall not crash (assertion failed)

# cleanup
cleanupTests
return

# vi:set ts=4 sw=4 et:
# Local Variables:
# mode: tcl
# End:
Changes to tests/bitmap.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/border.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to 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
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23

24
25

26
27

28
29

30
31

32
33

34
35

36
37
38
39

40
41

42
43
44

45
46
47
48

49
50

51
52
53

54
55
56
57

58
59

60
61
62

63
64
65
66

67
68

69
70
71

72
73
74
75
76
77
78
79

80
81

82
83

84
85

86
87

88
89

90
91

92
93
94
95
96
97
98
99






-
+












-
+



-
+

-
+

-


-
+

-
+

-


-
+



-
+

-



-
+



-
+

-



-
+



-
+

-



-
+



-
+

-



-
+







-
+

-
+

-


-
+

-
+

-


-
+







# 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.
# Copyright (c) 1998-2000 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 ...?"}
} -result {wrong # args: should be "tk busy options ?arg 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 ...?"}
} -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 .]
    tk busy hold .
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
} -result {}
test busy-2.3 {tk busy hold root window with shortcut} -body {
    set res [tk busy .]
    tk busy .
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
} -result {}
test busy-2.4 {tk busy hold nested window} -setup {
    pack [frame .f]
} -body {
    set res [tk busy hold .f]
    tk busy hold .f
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f_Busy}
} -result {}
test busy-2.5 {tk busy hold nested window with shortcut} -setup {
    pack [frame .f]
} -body {
    set res [tk busy .f]
    tk busy .f
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f_Busy}
} -result {}
test busy-2.6 {tk busy hold toplevel window} -setup {
    toplevel .f
} -body {
    set res [tk busy hold .f]
    tk busy hold .f
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f._Busy}
} -result {}
test busy-2.7 {tk busy hold toplevel window with shortcut} -setup {
    toplevel .f
} -body {
    set res [tk busy .f]
    tk busy .f
    update
    set res
} -cleanup {
    tk busy forget .f
    destroy .f
} -result {.f._Busy}
} -result {}
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"}
} -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]
    tk busy hold . -cursor arrow
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
} -result {}
test busy-2.11 {tk busy hold (shortcut) root window, cursor} -body {
    set res [tk busy . -cursor arrow]
    tk busy . -cursor arrow
    update
    set res
} -cleanup {
    tk busy forget .
} -result {._Busy}
} -result {}
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 {
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184







-
+







} -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 ...?"}
} -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]
476
477
478
479
480
481
482
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
468
469
470
471
472
473
474
475
























476
477








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


    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/butGeom2.tcl.
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18










-
+







# This file creates a visual test for button layout.  It is part of
# the Tk visual test suite, which is invoked via the "visual" script.

catch {destroy .t}
toplevel .t
wm title .t "Visual Tests for Button Geometry"
wm iconname .t "Button Geometry"
wm geom .t +0+0
wm minsize .t 1 1

label .t.l -text {This screen exercises the color options for various flavors of buttons.  Select display options below, and they will be applied to the appropiate button widgets.} -wraplength 5i
label .t.l -text {This screen exercises the color options for various flavors of buttons.  Select display options below, and they will be applied to the appropriate button widgets.} -wraplength 5i
pack .t.l -side top -fill both

button .t.quit -text Quit -command {destroy .t}
pack .t.quit -side bottom -pady 2m

set sepId 1
proc sep {} {
Changes to tests/button.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453
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
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
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







-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+







    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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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}
} -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}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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}
} -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}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
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
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







-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+







    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}
} -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}
} -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}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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}
} -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}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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
1482
1483
1484
1485
1486
1487
1488
1489

1490
1491
1492
1493
1494
1495
1496
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496







-
+







    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}
} -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
1505
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519
1505
1506
1507
1508
1509
1510
1511

1512
1513
1514
1515
1516
1517
1518
1519







-
+







    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}
} -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
1528
1529
1530
1531
1532
1533
1534
1535

1536
1537
1538
1539
1540
1541
1542
1528
1529
1530
1531
1532
1533
1534

1535
1536
1537
1538
1539
1540
1541
1542







-
+







    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}
} -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
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
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







-
+



















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+







    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}
} -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"}
} -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"}
} -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}
} -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}
} -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}
} -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}
} -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}
} -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}
} -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
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
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







-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+



















-
+



















-
+



















-
+


















-
+


















-
+


















-
+



















-
+


















-
+







    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}
} -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}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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}
} -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}
} -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}
} -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"}
} -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"}
} -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
2120
2121
2122
2123
2124
2125
2126
2127

2128
2129
2130
2131
2132
2133
2134
2120
2121
2122
2123
2124
2125
2126

2127
2128
2129
2130
2131
2132
2133
2134







-
+







    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}
} -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
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
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







-
+



















-
+


















-
+


















-
+


















-
+







    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}
} -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}
} -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}
} -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}
} -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}
} -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"
2367
2368
2369
2370
2371
2372
2373
2374

2375
2376
2377
2378
2379
2380
2381
2367
2368
2369
2370
2371
2372
2373

2374
2375
2376
2377
2378
2379
2380
2381







-
+







    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}
} -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
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
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







-
+



















-
+


















-
+


















-
+


















-
+







    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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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
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
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







-
+


















-
+


















-
+


















-
+



















-
+


















-
+


















-
+


















-
+













-
+







    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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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 ...?"}
} -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}
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
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







-
+







-
+
















-
+




















-
+





-
+





-
+





-
+





-
+







-
+





-
+





-
+






-
+





-
+






-
+





-
+



















-
+






-
+














-
+





-
+





-
+







    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"}
} -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"}
} -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"}
} -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 ...?"}
} -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}
} -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}
} -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"}
} -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"}
} -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 {*}
} -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 {*}
} -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"}
} -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 {*}
} -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"}
} -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 {*}
} -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"}
} -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"}
} -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}
} -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"}
} -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}
} -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}
} -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 {
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
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







-
+



-
-
+
+



-
+



-
+

-
+






-
+



-
-
+
+



-
+




-
+










-
+





-
+





-
+





-
+





-
+






-
+





-
+







} -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
    trace add variable checkvar write bogusTrace
    .c deselect
} -cleanup {
    destroy .c
    trace vdelete checkvar w bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
    trace remove variable checkvar write bogusTrace
} -returnCodes error -match glob -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
    trace add variable checkvar write bogusTrace
    catch {.c deselect}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    trace remove variable checkvar write bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
} -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
    trace add variable radiovar write bogusTrace
    .r deselect
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match {glob} -returnCodes {error} -result {can't set "radiovar": trace aborted}
    trace remove variable radiovar write 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
    trace add variable radiovar write bogusTrace
    catch {.r deselect}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
    trace remove variable radiovar write 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"}
} -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}
} -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 {*}
} -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 {*}
} -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 {*}
} -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}
} -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"}
} -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 {
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
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







-
+





-
+





-
+



















-
+



-
-
+
+



-
+




-
-
+
+










-
+





-
+





-
+





-
+
















-
+



-
-
+
+



-
+



-
+

-
+






-
+


-
+

-
+



-
+



-
+

-
+












-
+










-
+







} -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}
} -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}
} -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"}
} -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
    trace add variable radiovar write bogusTrace
    .r select
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -returnCodes {error} -result {can't set "radiovar": trace aborted}
    trace remove variable radiovar write bogusTrace
} -returnCodes error -match glob -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
    trace add variable radiovar write bogusTrace
    catch {.r select}
    list $errorInfo $radiovar
} -cleanup {
    destroy .r
    trace vdelete radiovar w bogusTrace
} -match {glob} -result {{*trace aborted
    trace remove variable radiovar write 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}
} -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}
} -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}
} -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"}
} -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
    trace add variable checkvar write bogusTrace
    .c toggle
} -cleanup {
    destroy .c
    trace vdelete checkvar w bogusTrace
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
    trace remove variable checkvar write bogusTrace
} -returnCodes error -match glob -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
    trace add variable checkvar write bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    trace remove variable checkvar write bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
} -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
    trace add variable checkvar write bogusTrace
    .c toggle
} -cleanup {
    trace vdelete checkvar w bogusTrace
    trace remove variable checkvar write bogusTrace
    destroy .c
} -returnCodes {error} -result {can't set "checkvar": trace aborted}
} -returnCodes error -match glob -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
    trace add variable checkvar write bogusTrace
    catch {.c toggle}
    list $errorInfo $checkvar
} -cleanup {
    trace vdelete checkvar w bogusTrace
    trace remove variable checkvar write bogusTrace
    destroy .c
} -match {glob} -result {{*trace aborted
} -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}
} -returnCodes error -match glob -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
} -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
3217
3218
3219
3220
3221
3222
3223
3224

3225
3226
3227
3228
3229
3230
3231
3217
3218
3219
3220
3221
3222
3223

3224
3225
3226
3227
3228
3229
3230
3231







-
+







} -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"}
} -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}
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
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







-
+



-
-
+
+





-
+







} -cleanup {
    destroy .r
} -result {}

test button-5.10 {ConfigureButton - error in setting variable} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    trace add variable x write bogusTrace
    radiobutton .r -variable x
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
    trace remove variable x write bogusTrace
} -returnCodes error -match glob -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}
} -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 {
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
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







-
+


-
+

-
+



-
+



-
+









-
+















-
+
















-
+




















-
+







} -cleanup {
    destroy .b
} -result {Override}

test button-5.14 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    trace add variable x write bogusTrace
    radiobutton .r -text foo -textvariable x
} -cleanup {
    trace vdelete x w bogusTrace
    trace remove variable x write bogusTrace
    destroy .r
} -returnCodes {error} -result {can't set "x": trace aborted}
} -returnCodes error -match glob -result {can*t set "x": trace aborted}
test button-5.15 {ConfigureButton - variable handling} -setup {
    unset -nocomplain x
} -body {
    trace variable x w bogusTrace
    trace add variable x write bogusTrace
    catch {radiobutton .r -text foo -textvariable x}
	return $x
} -cleanup {
    trace vdelete x w bogusTrace
    trace remove variable x write 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"}
} -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"}
} -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"}
} -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"}
} -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
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
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







-
+



-
-
+
+




-
+




-
+





-
+



-
-
+
+




-
+




-
+


















-
+



-
-
+
+



-
+




-
-
+
+







    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
    trace add variable x write bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
    trace remove variable x write bogusTrace
} -returnCodes error -match glob -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
    trace add variable x write bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
    trace remove variable x write bogusTrace
} -result 1
test button-8.4 {TkInvokeButton procedure} -setup {
    set x 1
} -body {
    checkbutton .c -variable x
    trace variable x w bogusTrace
    trace add variable x write bogusTrace
    .c invoke
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
    trace remove variable x write bogusTrace
} -returnCodes error -match glob -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
    trace add variable x write bogusTrace
    catch {.c invoke}
    return $x
} -cleanup {
    destroy .c
    trace vdelete x w bogusTrace
    trace remove variable x write 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
    trace add variable x write bogusTrace
    .r invoke
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace
} -returnCodes {error} -result {can't set "x": trace aborted}
    trace remove variable x write bogusTrace
} -returnCodes error -match glob -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
    trace add variable x write bogusTrace
    catch {.r invoke}
    list $errorInfo $x
} -cleanup {
    destroy .r
    trace vdelete x w bogusTrace
} -match {glob} -result {{*trace aborted
    trace remove variable x write bogusTrace
} -match glob -result {{*trace aborted
    while executing
*
".r invoke"} red}

#ex 9.6
test button-8.9 {TkInvokeButton procedure} -setup {
    set result untouched
Changes to tests/canvImg.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86
87

88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86

87
88
89
90
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149







-
+














-
+















-
+




-
+













-
+




-
+




-
+



















-
+









-
+









-
+









-
+







} -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}
} -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}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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}
} -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
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176







-
+







    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"}]
    set timer [after 500 {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
    }
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205







-
+







    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}
} -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
357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
357
358
359
360
361
362
363



364

365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383







-
-
-

-
+










-
+







    .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
    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}}
} -result {{foo display 4 9 12 6}}
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 {}
Changes to tests/canvMoveto.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 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
Changes to tests/canvPs.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
129
130
131
132
133
134
135

136


137
138
139
140
141
142
143







-
+
-
-







} -cleanup {
    removeFile foo.ps
    removeFile bar.ps
} -result ok
destroy .c


test canvPs-3.1 {test ps generation with an embedded window} -constraints {
test canvPs-3.1 {test ps generation with an embedded window} -setup {
    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
176
177
178
179
180
181
182


















183
184
185
186
187
188
189
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









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 *


test canvPs-5.1 {test ps generation with bitmap, bug 424773a00c} -body {
    pack [canvas .c]
    update
    .c create bitmap 50 50 -bitmap questhead
    .c postscript  ; # was crashing on macOS
} -cleanup {
    destroy .c
} -returnCodes ok -match glob -result *
test canvPs-5.2 {test ps generation with image} -body {
    pack [canvas .c]
    update
    .c create image 50 50 -image ::tk::icons::information
    .c postscript
} -cleanup {
    destroy .c
} -returnCodes ok -match glob -result *


# cleanup
unset -nocomplain foo bar
imageFinish
Changes to tests/canvRect.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
119
120
121
122
123
124
125

126


127

128
129
130
131
132
133
134







-
+
-
-

-







} -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 {
test canvRect-3.6 {RectOvalCoords procedure} -body {
    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
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173







174

175
176
177
178
179
180
181
182


183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
153
154
155
156
157
158
159

160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177

178
179
180
181
182


183
184

185
186
187
188
189
190
191

192

193
194
195
196
197
198
199

200

201
202
203
204
205
206
207







-
+
-









+
+
+
+
+
+
+
-
+
-





-
-
+
+
-







-
+
-







-
+
-







} -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 {
test canvRect-4.4 {ConfigureRectOval procedure} -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.

# On Windows the bbox of rectangle items is 1 pixel larger at each border due
# to the "bloat" implemented in ComputeRectOvalBbox() in case -outline is {}
if {[tk windowingsystem] eq "win32"} {
    set result_5_1 {9 4 21 16}
} else {
    set result_5_1 {10 5 20 15}
}
test canvRect-5.1 {ComputeRectOvalBbox procedure} -constraints nonPortable -body {
test canvRect-5.1 {ComputeRectOvalBbox procedure} -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 {
} -result $result_5_1
test canvRect-5.2 {ComputeRectOvalBbox procedure} -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 {
test canvRect-5.3 {ComputeRectOvalBbox procedure} -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 {
test canvRect-5.4 {ComputeRectOvalBbox procedure} -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}
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439


440
441
442
443
444
445
446
423
424
425
426
427
428
429

430
431
432
433


434


435
436
437
438
439
440
441
442
443







-
+



-
-

-
-
+
+







    .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
    nonPortable
} -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).
    # 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
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
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 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.
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
94
95
96
97
98
99
100
101

102
103
104
105
106

107
108
109
110
111

112
113
114
115
116

117
118
119
120
121
122
123
91
92
93
94
95
96
97

98
99
100
101
102

103
104
105
106
107

108
109
110
111
112

113
114
115
116
117
118
119
120







-
+




-
+




-
+




-
+







    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 ...?"}
} -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"}
} -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"}
} -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"}
} -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}

132
133
134
135
136
137
138
139

140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
129
130
131
132
133
134
135

136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185







-
+






-
+


















-
+






-
+








-
+







} -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"}
} -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"}
} -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}
} -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}
} -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"}
} -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
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
632
633
634
635
636
637
638

639
640
641
642
643
644
645
646







-
+







} -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}
} -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}
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
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







-
+









-
+









-
+








-
+







    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}
} -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}
} -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."}
} -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"}
} -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\""
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
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







-
+






+
+
+
+
+
+

-
+







+
-
-
-
+
+
+







    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 {
test canvText-20.1 {angled text bounding box} -setup {
    destroy .c
    canvas .c
    proc transpose {bbox} {
	lassign $bbox a b c d
	list $b $a $d $c
    }
    proc almosteq {b1 b2} {
        # check whether the two boxes are equal, with 1 unit tolerance on each x y w h
        lassign $b1 a b c d
        lassign $b2 e f g h
        expr {($e-$a)<=1 && ($f-$b)<=1 && ($g-$c)<=1 && ($h-$d)<=1}
    }
} -body {
    .c create text 2 2 -tag t -anchor center -text 0 -font {Helvetica 24}
    .c create text 2 2 -tag t -anchor center -text 0 -font {TkDefaultFont 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]
    # bboxes should be the same, possibly with a small (platform-specific) rounding difference
    list [expr {$bb0 eq $bb2 ? "ok" : "$bb0,$bb2"}] \
	[expr {$bb1 eq $bb3 ? "ok" : "$bb1,$bb3"}] \
	[expr {$bb0 eq [transpose $bb1] ? "ok" : "$bb0,$bb1"}] \
    list [expr {[almosteq $bb0 $bb2] ? "ok" : "$bb0,$bb2"}] \
	[expr {[almosteq $bb1 $bb3] ? "ok" : "$bb1,$bb3"}] \
	[expr {[almosteq $bb0 [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
Changes to tests/canvWind.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

134
135
136
137
138
139
140
















141
142
143
144
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




    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}}

test canvWind-2.1 {DisplayWinItem, window gets destroyed during <Configure>} -setup {
    destroy .t
} -body {
    toplevel .t
    canvas .t.c
    pack .t.c
    frame .t.c.f -width 50 -height 50 -background red
    set id [.t.c create window 50 50 -window .t.c.f]
    update
    bind .t.c.f <Configure> {destroy .t.c.f}
    .t.c coords $id 60 60 ;  # was crashing
    update
} -cleanup {
    destroy .t
} -result {}

# cleanup
cleanupTests
return
Changes to tests/canvas.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2008 Donal K. Fellows
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit

129
130
131
132
133
134
135
136

137
138
139
140
141


142
143
144
145
146
147
148
129
130
131
132
133
134
135

136
137
138
139


140
141
142
143
144
145
146
147
148







-
+



-
-
+
+







    .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 configure -relief g
    .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}
    .c configure -relief r
} -returnCodes error -result {bad relief "r": 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"}
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
212
213
214
215
216
217
218

219


220
221
222
223
224
225
226
227










228
229
230
231
232
233
234







-
+
-
-








-
-
-
-
-
-
-
-
-
-







    .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 {
test canvas-2.4 {CanvasWidgetCmd, xview option} -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
346
347
348
349
350
351
352
353
354
355
356


357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
334
335
336
337
338
339
340




341
342
















343
344
345
346
347
348
349







-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







} -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}}
    list $arcBox $coordBox $pieBox
} -result {{48 21 100 94} {248 21 300 94} {398 21 500 112}}
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
556
557
558
559
560
561
562







563
564
565
566
567
568
569
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546







+
+
+
+
+
+
+







    # This would crash
    destroy .c
    pack [canvas .c]
    .c create polygon 0 0 0 10 10 0
    .c dchars 1 2 end
    .c coords 1
} {}
test canvas-11.4 {canvas line dchars crash with -arrows, bug 51ece3786f} {
    # This would crash
    destroy .c
    canvas .c
    .c create line 10 10 100 100 -arrow last
    .c dchars 1 0 1
} {}

test canvas-12.1 {canvas mm obj, patch SF-403327, 102471} -setup {
    destroy .c
    pack [canvas .c]
} -body {
    set qx [expr {1.+1.}]
    # qx has type double and no string representation
596
597
598
599
600
601
602
603

604
605
606
607
608
609
610
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587







-
+







    }]
}
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 <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
751
752
753
754
755
756
757
758

759
760
















761
762
763
764
765
766
767
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







-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







} -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]
    set id [.c create rect 0 0 1c 1c]
    expr {[lindex [.c coords $id] 2]>1}
} -result 1
test canvas-15.20 {bug [237971ce]} -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create line {0 0 50 50 100 50}]
    .c insert $id end {200 200}
    .c coords $id
} -result {0.0 0.0 50.0 50.0 100.0 50.0 200.0 200.0}
test canvas-15.21 {bug [237971ce]} -setup {
    destroy .c
    canvas .c
} -body {
    set id [.c create poly {0 0 50 50 100 50}]
    .c insert $id end {200 200}
    .c coords $id
} -result {0.0 0.0 50.0 50.0 100.0 50.0 200.0 200.0}
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
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
1009
1010
1011
1012
1013
1014
1015















































































































































































































































































1016
1017
1018
1019
1020
1021
1022
1023







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








    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:
Changes to tests/choosedir.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36







-
+








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 <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
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+








    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <Key> -keysym Return
	event generate $w <KeyPress> -keysym Return
    }
}


#----------------------------------------------------------------------
#
# The test suite proper
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
1
2
3
4


5
6
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 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.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
}

231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243







-
+







    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 {
test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints x11 -setup {
    clipboard clear
} -body {
    setupbg
    clipboard append -f INTEGER -t TEST "16"
    set result [dobg {clipboard get TEST}]
    return $result
} -cleanup {
Changes to tests/clrpick.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+







	    }
	}
	.c delete $i
	incr i
    }
    destroy .c
} else {
    testConstraint colorsLeftover 0
    testConstraint colorsLeftover 1
}

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 {
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107







-
+



















-
+







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
# before setting 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 <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

133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
133
134
135
136
137
138
139

140
141
142

143
144
145
146
147

148












149
150
151
152
153
154
155







-
+


-





-
+
-
-
-
-
-
-
-
-
-
-
-
-








    if {$type == "mouse"} {
	PressButton $button
    } else {
	event generate $w <Enter>
	focus $w
	event generate $button <Enter>
	event generate $w <Key> -keysym Return
	event generate $w <KeyPress> -keysym Return
    }
}



test clrpick-2.1 {tk_chooseColor command} -constraints {
    nonUnixUserInteraction colorsLeftover
} -setup {
    set verylongstring longstring:
    set verylongstring [string repeat longstring: 100]
    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
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
1
2
3


4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19

20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49



-
-
+
+











-
+


-
+


-
+


















-
+







# 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.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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"}
} -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"}
} -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"}
} -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}
} -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}
Changes to tests/color.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1995-1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands

# cname --
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173







-
+







    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
	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
	}

    }
    return $result
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







-
+













-
+







    winfo rgb . #abz
} -returnCodes error -result {invalid color name "#abz"}
test color-2.11 {Tk_GetColor, 6 hex digits, last one invalid} -body {
    winfo rgb . #12345g
} -returnCodes error -result {invalid color name "#12345g"}

test color-3.1 {Tk_FreeColor procedure, reference counting} colorsFree {
    eval destroy [winfo child .t]
    destroy {*}[winfo children .t]
    mkColors .t.c 40 6 0 240 240 0 -6 0 0 0 -40
    pack .t.c
    mkColors .t.c2 20 1 250 0 0 -10 0 0 0 0 0
    pack .t.c2
    update
    set last [.t.c2 create rectangle 50 50 70 60 -outline {} \
	    -fill [cname 0 240 240]]
    .t.c delete 1
    set result [colorsFree .t]
    .t.c2 delete $last
    lappend result [colorsFree .t]
} {0 1}
test color-3.2 {Tk_FreeColor procedure, flushing stressed cmap information} colorsFree {
    eval destroy [winfo child .t]
    destroy {*}[winfo children .t]
    mkColors .t.c 40 6 0 240 240 0 -6 0 0 0 -40
    pack .t.c
    mkColors .t.c2 20 1 250 0 0 -10 0 0 0 0 0
    mkColors .t.c2 20 1 250 250 0 -10 -10 0 0 0 0
    pack .t.c2
    update
    closest .t 241 241 1
Changes to tests/config.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60







-
+







-
+







    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}}
} -result {{1 17 -boolean} {2 17 -boolean}}
test config-1.2 {Tk_CreateOptionTable - synonym initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a -synonym green
    .a cget -color
} -cleanup {
    killTables
} -result {green}
} -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]
73
74
75
76
77
78
79
80

81
82
83

84
85
86
87
88
89
90
73
74
75
76
77
78
79

80
81
82

83
84
85
86
87
88
89
90







-
+


-
+







    killTables
    option clear
} -result {foo bar}
test config-1.5 {Tk_CreateOptionTable - default initialization} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -relief
    .a cget -anchor
} -cleanup {
    killTables
} -result {raised}
} -result center
test config-1.6 {Tk_CreateOptionTable - chained tables} -constraints {
    testobjconfig
} -body {
    testobjconfig chain1 .a
    testobjconfig chain2 .b
    testobjconfig info chain2
} -cleanup {
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177

178
179
180
181
182

183
184
185
186
187
188
189
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176

177
178
179
180
181

182
183
184
185
186
187
188
189







-
+









-
+







-
+




-
+







} -body {
    option add *a.color blue
    testobjconfig alltypes .a
    list [.a cget -color]
} -cleanup {
    killTables
    option clear
} -result {blue}
} -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}
} -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}
} -result red
test config-3.5 {Tk_InitOptions - no initial value} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .a
    .a cget -anchor
    .a cget -relief
} -cleanup {
    killTables
} -result {}
test config-3.6 {Tk_InitOptions - bad initial value} -constraints {
    testobjconfig
} -body {
    option add *a.color non-existent
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237







-
+








test config-4.1 {DoObjConfig - boolean} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -boolean 0
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261







-
+







} -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}
} -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
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305







-
+








test config-4.9 {DoObjConfig - integer} -constraints testobjconfig -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig alltypes .foo -integer 3
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359







-
+







-
+








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}
} -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}
} -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 {
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419







-
+







-
+







-
+















-
+







} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -double 62.75
    .foo cget -double
} -cleanup {
    killTables
} -result {62.75}
} -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}
} -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}
} -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}
} -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
439
440
441
442
443
444
445
446

447
448
449
450
451
452

453
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
439
440
441
442
443
444
445

446
447
448
449
450
451

452
453
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







-
+





-
+














-
+
+
+
+
+
+
+
















-
+



















-
+





-
+





-
+







    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}
} -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}
} -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.29a {DoObjConfig - invalid string table} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -stringtable2 foo
} -cleanup {
    killTables
} -returnCodes error -result {bad stringtable2 "foo": must be one or two}
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}
} -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}
} -result four

test config-4.34 {DoObjConfig - color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color blue
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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}
} -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
533
534
535
536
537
538
539
540

541
542
543
544
545
546

547
548
549
550
551
552
553
539
540
541
542
543
544
545

546
547
548
549
550
551

552
553
554
555
556
557
558
559







-
+





-
+







} -setup {
    catch {rename .foo {}}
} -body {
    testobjconfig internal .foo -color purple
    .foo cget -color
} -cleanup {
    killTables
} -result {purple}
} -result purple

test config-4.39 {DoObjConfig - null color} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -color {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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 {
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607







-
+








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}
} -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
628
629
630
631
632
633
634
635

636
637
638
639
640
641
642
634
635
636
637
638
639
640

641
642
643
644
645
646
647
648







-
+







} -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}
} -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
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
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







-
+





-
+












-
+











-
+















-
+





-
+





-
+











-
+







    killTables
} -result {Times 16}

test config-4.53 {DoObjConfig - bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap gray75
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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}
} -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}
} -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}
} -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}
} -result gray25

test config-4.61 {DoObjConfig - border} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -border green
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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}
} -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}
} -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 {
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
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







-
+





-
+














-
+












-
+





-
+





-
+











-
+




















-
+









-
+





-
+





-
+

















-
+









-
+





-
+





-
+

















-
+









-
+




-
+







    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}
} -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}
} -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}
} -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}
} -returnCodes ok -result flat

test config-4.75 {DoObjConfig - cursor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -cursor arrow
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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}
} -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}
} -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}
} -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}
} -result watch

test config-4.83 {DoObjConfig - justify} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -justify center
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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}
} -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}
} -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}
} -result center

test config-4.89 {DoObjConfig - anchor} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -anchor center
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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}
} -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}
} -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}
} -result sw
test config-4.95 {DoObjConfig - pixel} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -pixel 42
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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 {
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
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







-
+


















-
+






-
+











-
+







} -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}
} -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}
} -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}
} -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}
} -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 {}
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
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







-
+









-
+







    toplevel .bar
    toplevel .blamph
    testobjconfig twowindows .foo -window .bar
    .foo configure -window .blamph
    .foo cget -window
} -cleanup {
    killTables
} -returnCodes ok -result {.blamph}
} -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 {.}
} -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
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
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







-
+





-
+




-
+







    killTables
} -result {}

test config-4.111 {DoObjConfig - custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom test
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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}
} -returnCodes ok -result TEST
test config-4.113 {DoObjConfig - null custom} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -custom {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
} -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 {
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
1153
1154
1155
1156
1157
1158
1159

1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174
1175







-
+







-
+







test config-6.2 {GetOptionFromObj - exact match} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -one
} -cleanup {
    killTables
} -result {one}
} -result one
test config-6.3 {GetOptionFromObj - abbreviation} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -fo
} -cleanup {
    killTables
} -result {four}
} -result four
test config-6.4 {GetOptionFromObj - ambiguous abbreviation} -constraints {
    testobjconfig
} -body {
    testobjconfig chain2 .a
    .a cget -on
} -cleanup {
    killTables
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
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







-
+

















-
+










-
+







    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}
} -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}
} -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}
} -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 {
1292
1293
1294
1295
1296
1297
1298
1299

1300
1301
1302
1303
1304
1305
1306
1298
1299
1300
1301
1302
1303
1304

1305
1306
1307
1308
1309
1310
1311
1312







-
+







} -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}
} -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
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
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







-
+








-
+








-
+








-
+

















-
+








-
-
+
+



-
-
+
+


-
+








-
+








-
+




-
+



-
+








-
+








-
+







    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -double 62.4 -color bogus}
    .a cget -double
} -cleanup {
    killTables
} -result {3.14159}
} -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}
} -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}
} -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}
} -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}
} -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 {
} -result blue
test config-8.15 {Tk_RestoreSavedOptions - anchor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -relief sunken -color bogus}
    .a cget -relief
    catch {.a csave -anchor e -color bogus}
    .a cget -anchor
} -cleanup {
    killTables
} -result {raised}
} -result center
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}
} -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}
} -result left
test config-8.18 {Tk_RestoreSavedOptions - anchor internal form} -constraints {
    testobjconfig
} -body {
    testobjconfig internal .a
    catch {.a csave -anchor center -color bogus}
    catch {.a csave -anchor n -color bogus}
    .a cget -anchor
} -cleanup {
    killTables
} -result {n}
} -result center
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}
} -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}
} -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
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
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







-
-
+
+


-
+
















-
+







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
    .foo configure -anchor e
    .foo configure -anchor
} -cleanup {
    destroy .foo
} -result {-relief relief Relief raised groove}
} -result {-anchor anchor Anchor center e}
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}}
} -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} {-stringtable2 StringTable2 stringTable2 two two} {-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 {} {}} {-cursor cursor Cursor xterm xterm} {-justify {} {} left left} {-anchor anchor Anchor center center} {-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]} {
1603
1604
1605
1606
1607
1608
1609
1610
1611


1612
1613
1614
1615
1616
1617
1618
1609
1610
1611
1612
1613
1614
1615


1616
1617
1618
1619
1620
1621
1622
1623
1624







-
-
+
+







    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 {} {}}
    .a configure -relief
} -result {-relief relief Relief {} {}}
if {[testConstraint testobjconfig]} {
    killTables
}


if {[testConstraint testobjconfig]} {
    testobjconfig internal .a
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
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







-
+



-
+







-
+









-
+





-
+





-
+



-
+







-
+



-
+







    .a cget -string
} -result {test value}
test config-12.5 {GetObjectForOption - stringTable} -constraints {
    testobjconfig
} -body {
    .a configure -stringtable "two"
    .a cget -stringtable
} -result {two}
} -result two
test config-12.6 {GetObjectForOption - color} -constraints testobjconfig -body {
    .a configure -color "green"
    .a cget -color
} -result {green}
} -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}
} -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}
} -result groove
test config-12.11 {GetObjectForOption - cursor} -constraints {
    testobjconfig
} -body {
    .a configure -cursor watch
    .a cget -cursor
} -result {watch}
} -result watch
test config-12.12 {GetObjectForOption - justify} -constraints {
    testobjconfig
} -body {
    .a configure -justify right
    .a cget -justify
} -result {right}
} -result right
test config-12.13 {GetObjectForOption - anchor} -constraints testobjconfig -body {
    .a configure -anchor e
    .a cget -anchor
} -result {e}
} -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}
} -result .a
test config-12.16 {GetObjectForOption -custom} -constraints testobjconfig -body {
    .a configure -custom foobar
    .a cget -custom
} -result {FOOBAR}
} -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] \
Changes to tests/constraints.tcl.
117
118
119
120
121
122
123
124







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151







-
+
+
+
+
+
+
+














-







	}
	Export bg::setup as setupbg
	Export bg::cleanup as cleanupbg
	Export bg::do as dobg

	namespace export deleteWindows
	proc deleteWindows {} {
	    eval destroy [winfo children .]
	    destroy {*}[winfo children .]
	    # This update is needed to avoid intermittent failures on macOS in unixEmbed.test
	    # with the (GitHub Actions) CI runner.
	    # Reason for the failures is unclear but could have to do with window ids being deleted
	    # after the destroy command returns. The detailed mechanism of such delayed deletions
	    # is not understood, but it appears that this update prevents the test failures.
	    update
	}

	namespace export fixfocus
	proc fixfocus {} {
            catch {destroy .focus}
            toplevel .focus
            wm geometry .focus +0+0
            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]]
168
169
170
171
172
173
174








































































175
176
177
178
179
180
181
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







            set r {}
            foreach img [image names] {
                if {$img ni $ImageNames} {lappend r $img}
            }
            return $r
        }

	#
	#  CONTROL TIMING ASPECTS OF POINTER WARPING
	#
	# The proc [controlPointerWarpTiming] is intended to ensure that the (mouse)
	# pointer has actually been moved to its new position after a Tk test issued:
	#
	#    [event generate $w $event -warp 1 ...]
	#
	# It takes care of the following timing details of pointer warping:
	#
	# a. Allow pointer warping to happen if it was scheduled for execution at
	#    idle time.
	#    - In Tk releases 8.6 and older, pointer warping is scheduled for
	#      execution at idle time
	#    - In release 8.7 and newer this happens synchronously if $w refers to the
	#      whole screen or if the -when option to [event generate] is "now".
	#    The namespace variable idle_pointer_warping records which of these is
	#    the case.
	#
	# b. Work around a race condition associated with OS notification of
	#    mouse motion on Windows.
	#
	#    When calling [event generate $w $event -warp 1 ...], the following
	#    sequence occurs:
	#    - At some point in the processing of this command, either via a
	#      synchronous execution path, or asynchronously at idle time, Tk calls
	#      an OS function* to carry out the mouse cursor motion.
	#    - Tk has previously registered a callback function** with the OS, for
	#      the OS to call in order to notify Tk when a mouse move is completed.
	#    - Tk doesn't wait for the callback function to receive the notification
	#      from the OS, but continues processing. This suits most use cases
	#      because usually the notification arrives fast enough (within a few tens
	#      of microseconds). However ...
	#    - A problem arises if Tk performs some processing, immediately following
	#      up on [event generate $w $event -warp 1 ...], and that processing
	#      relies on the mouse pointer having actually moved. If such processing
	#      happens just before the notification from the OS has been received,
	#      Tk will be using not yet updated info (e.g. mouse coordinates).
	#
	#         Hickup, choke etc ... !
	#
	#            *  the function SendInput() of the Win32 API
	#            ** the callback function is TkWinChildProc()
	#
	#    This timing issue can be addressed by putting the Tk process on hold
	#    (do nothing at all) for a somewhat extended amount of time, while
	#    letting the OS complete its job in the meantime. This is what is
	#    accomplished by calling [after ms].
	#
	#    ----
	#    For the history of this issue please refer to Tk ticket [69b48f427e],
	#    specifically the comment on 2019-10-27 14:24:26.
	#
	#
	# Beware: there are cases, not (yet) exercised by the Tk test suite, where
	# [controlPointerWarpTiming] doesn't ensure the new position of the pointer.
	# For example, when issued under Tk8.7+, if the value for the -when option
	# to [event generate $w] is not "now", and $w refers to a Tk window, i.e. not
	# the whole screen.
	#
	variable idle_pointer_warping [expr {![package vsatisfies [package provide Tk] 8.7-]}]
	proc controlPointerWarpTiming {{duration 50}} {
		variable idle_pointer_warping
		if {$idle_pointer_warping} {
			update idletasks ;# see a. above
		}
		if {[tk windowingsystem] eq "win32"} {
			after $duration ;# see b. above
		}
	}
	namespace export controlPointerWarpTiming

    }
}

namespace import -force tk::test::*

namespace import -force tcltest::testConstraint
testConstraint notAqua [expr {[tk windowingsystem] ne "aqua"}]
191
192
193
194
195
196
197



198
199
200
201
202
203
204
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284







+
+
+







    ([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"}]
}]
# constraint for running a test on all windowing system except aqua
# where the test fails due to a known bug
testConstraint aquaKnownBug [expr {[testConstraint notAqua] || [testConstraint knownBug]}]

# 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]]
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237












238
239





240
















241
242

243
244
245
246
247
248
249
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329


330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360







-
+


















+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+







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
# constraints about 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
pack .t
.t insert end "This is\na dot."
update
set x [list [.t bbox 1.3] [.t bbox 2.5]]
destroy .t
if {![string match {{22 3 6 15} {31 18 [34] 15}} $x]} {
    testConstraint fonts 0
}
# Although unexpected, some systems may have a very limited set of fonts available.
# The following constraints happen to evaluate to false at least on one system: the
# Github CI runner for Linux with --disable-xft, which has exactly ONE single font
# ([font families] returns a single element: "fixed"), for which [font actual]
# returns:
#    -family fixed -size 9 -weight normal -slant roman -underline 0
# and [font metrics] returns:
#    -ascent 11 -descent 2 -linespace 13 -fixed 1
# The following constraints are hence tailored to check exactly what is needed in the
# tests they constrain (that is: availability of any font having the given font
# attributes), so that these constrained tests will in fact run on all systems having
# reasonable font dotation.
testConstraint textfonts [expr {
    [testConstraint fonts] || [tk windowingsystem] eq "win32"
testConstraint haveTimes12Font [expr {
    [font actual {times 12} -size] == 12
}]
testConstraint haveCourier37Font [expr {
    [font actual {-family courier -size 37} -size] == 37
}]
testConstraint haveTimes14BoldFont [expr {
    ([font actual {times 14 bold} -size] == 14) &&
    ([font actual {times 14 bold} -weight] eq "bold")
}]
testConstraint haveTimes12BoldItalicUnderlineOverstrikeFont [expr {
    ([font actual {times 12 bold italic overstrike underline} -weight] eq "bold") &&
    ([font actual {times 12 bold italic overstrike underline} -slant] eq "italic") &&
    ([font actual {times 12 bold italic overstrike underline} -underline] eq "1") &&
    ([font actual {times 12 bold italic overstrike underline} -overstrike] eq "1")
}]
set fixedFont {Courier 12}   ; # warning: must be consistent with the files using the constraint below!
set bigFont   {Helvetica 24} ; # ditto
testConstraint haveBigFontTwiceLargerThanTextFont [expr {
    [font actual $fixedFont -size] * 2 <= [font actual $bigFont -size]
}]
unset fixedFont bigFont

# constraints for the visuals available..
# constraints for the visuals available
testConstraint pseudocolor8 [expr {
    ([catch {
	toplevel .t -visual {pseudocolor 8} -colormap new
    }] == 0) && ([winfo depth .t] == 8)
}]
destroy .t
testConstraint haveTruecolor24 [expr {
Added tests/corruptTruncatedColormap.gif.

cannot compute difference between binary files

Changes to tests/cursor.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/dialog.test.
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+















-
+








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 <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
        event generate $w <KeyPress> -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
Changes to tests/earth.gif.

cannot compute difference between binary files

Changes to tests/embed.test.
1
2
3
4


5
6
7
8
9
10
11
1
2


3
4
5
6
7
8
9
10
11


-
-
+
+







# This file is a Tcl script to test out embedded Windows.
#
# Copyright © 1996-1997 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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
1
2
3



4
5
6
7
8
9
10
11
12
13




14
15
16
17
18
19

20
21
22
23
24
25
26
27



-
-
-
+
+
+







-
-
-
-






-
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
# For trace add 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} {
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66

67
68
69
70

71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86

87
88
89
90

91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106

107
108
109
110

111
112
113
114
115
116
117
118
119
120

121
122
123
124
125
126

127
128
129
130

131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146

147
148
149
150

151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166

167
168
169
170

171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186

187
188
189
190

191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206

207
208
209
210

211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226

227
228
229
230

231
232
233
234
235
236
237
238
239
240

241
242
243
244
245
246

247
248
249
250

251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266

267
268
269
270

271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286

287
288
289
290

291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306

307
308
309
310

311
312
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336

337
338
339
340

341
342
343
344
345
346
347
348
349
350

351
352
353
354
355
356

357
358
359
360

361
362
363
364
365
366
367
368
369
370

371
372
373
374
375
376

377
378
379
380

381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396

397
398
399
400

401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416

417
418
419
420

421
422
423
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452

453
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
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61

62
63
64
65

66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81

82
83
84
85

86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101

102
103
104
105

106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121

122
123
124
125

126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141

142
143
144
145

146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161

162
163
164
165

166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181

182
183
184
185

186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201

202
203
204
205

206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221

222
223
224
225

226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241

242
243
244
245

246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261

262
263
264
265

266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281

282
283
284
285

286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301

302
303
304
305

306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331

332
333
334
335

336
337
338
339
340
341
342
343
344
345

346
347
348
349
350
351

352
353
354
355

356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371

372
373
374
375

376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391

392
393
394
395

396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411

412
413
414
415

416
417
418
419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453

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







-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+










-
+










-
+









-
+





-
+



-
+









-
+





-
+



-
+










-
+









-
+





-
+



-
+









-
+





-
+



-
+









-
+





-
+



-
+










-
+









-
+





-
+



-
+










-
+










-
+









-
+





-
+



-
+








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-










-
+







}

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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -background non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -bg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -cursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -disabledbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -disabledforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -exportselection xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -fg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -font {}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {font "" doesn't exist}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -foreground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightcolor non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -highlightthickness badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "2.6x"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertofftime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -insertontime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -justify bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad justification "bogus": must be left, right, or center}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -readonlybackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectborderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -selectforeground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -state bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad state "bogus": must be disabled, normal, or readonly}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e configure -width 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
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
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







-
+








-
+








-
+








-
+








-
+














-
+












-
+



-
+








-
+



-
+






-
+











-
+


-
+







} -cleanup {
    destroy .e
} -result {.e}


test entry-3.1 {EntryWidgetCmd procedure} -setup {
    entry .e
    pack .e
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
# Tcl_UtfAtIndex(): utf at end
    .e insert 0 "ab"
    .e insert 0 "ab\u4e4e"
    .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
    pack .e ; update idletasks
    update
} -body {
# Tcl_UtfAtIndex(): utf before index
    .e insert 0 "abc"
    .e insert 0 "ab\u4e4ec"
    .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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e insert 0 "abcdefghijklmnop"
    .e insert 0 "abcdefghij\u4e4eklmnop"
    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 {
820
821
822
823
824
825
826
827

828
829
830
831
832
833

834
835
836
837
838
839
840
799
800
801
802
803
804
805

806
807
808
809
810
811

812
813
814
815
816
817
818
819







-
+





-
+







    .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
    pack .e ; update idletasks
    update
} -body {
    llength [.e configure]
} -cleanup {
    destroy .e
} -result 38
} -result 36
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"}
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
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







-
+



















-
+




-
+



-
+



-
+




-
+


-
+










-
+












-
+







} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
    set x {}
} -body {
# UTF
    .e insert end "0123467890"
    .e insert end "01234\u4e4e67890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123457890"
    .e insert end "012345\u4e4e7890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456890"
    .e insert end "0123456\u4e4e890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "012347890" "0123457890" "012345890"]
} -result [list "01234\u4e4e7890" "0123457890" "012345\u4e4e890"]
test entry-3.25 {EntryWidgetCmd procedure, "delete" widget command} -setup {
    entry .e
    pack .e
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e insert end "01234567890"
    .e configure -state readonly
    .e delete 2 8
    .e configure -state normal
    .e get
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
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







-
+








-
+



-
+







} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
# UTF
    .e insert 0 abc乎œdef
    .e insert 0 abc\u4e4e\u0153def
    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 {
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
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







-
+










-
+












-
+



















-
+








-
+








-
+








-
+












-
+







} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
1174
1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188
1153
1154
1155
1156
1157
1158
1159

1160
1161
1162
1163
1164
1165
1166
1167







-
+







    .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
    pack .e ; update idletasks
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 4
    update
    .e select clear
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
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







-
+











-
+












-
+







} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e insert end 0123456789
    .e select from 3
    .e select to 6
    .e delete 0 end
    .e selection present
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
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







-
+













-
+







} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    update
} -body {
    .e insert end "0123456789"
    .e select from 1
    .e select to 5
    update
    .e select adjust 2
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
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







-
+












-
+













-
+













-
+











-
+











-
+








-
+













-
+








-
+








-
+











-
+







-
+


-
+







-
+


-
+












-
+













-
+













-
+













-
+







-
+


-
+










-
+













-
+











-
+



-
+

















-
+













-
+







    .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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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"}
} -returnCodes error -result {wrong # args: should be ".e xview scroll number units|pages"}
test entry-3.72 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    pack .e ; update idletasks
} -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"}
} -returnCodes error -result {expected integer but got "gorp"}
test entry-3.73 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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}
} -returnCodes error -result {bad argument "foobars": must be units or pages}
test entry-3.78 {EntryWidgetCmd procedure, "xview" widget command} -setup {
    entry .e -font {Courier -12} -borderwidth 2 -highlightthickness 2
    pack .e
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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 
    .e insert 10 \u4e4e
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    .e insert end "Sample text"
    update
    destroy .e
} -result {}

test entry-5.1 {ConfigureEntry procedure, -textvariable} -body {
    set x 12345
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
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







-
+





-
+











-
+














-
+











-
+













-
+



-
-
+
+

-
+



-
-
+



-
+


-
+














-
+












-
+










-
+















-
+













-
+













-
+











-
+











-
+













-
+













-
+












-
+












-
+











-
+
















-
+







} -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
    trace add variable x write override
    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
    trace remove variable x write 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
    pack .e1 .e2 ; update idletasks
    .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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -body {
    .e configure -font {Courier -12} -width 4 -xscrollcommand scroll
    .e insert end "01234567890"
    update idletasks
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    update
    set scrollInfo wrong
    .e configure -width 5
    vwait scrollInfo
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}
} -result {0.000000 0.454545}


test entry-5.8 {ConfigureEntry procedure} -constraints {
    fonts failsOnXQuarz
    fonts
} -setup {
    entry .e -borderwidth 2 -highlightthickness 2
    pack .e
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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}]
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
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







-
+












-
+



+
-
+


-
+



-





-
+



+
-
+


-
+



-



-
+













-
+













-
+













-
+













-
+











-
+










-
+











-
+














-
+












-
+



+
-
+


-
+



-




-
+



+
-
+


-
+



-




-
+



+
-
+


-
+



-



-
+















-
+















-
+















-
+













-
+















-
+












-
+















-
+















-
+












-
+












-
+












-
+












-
+












-
+










-
+

-
+


















-
+




-
+





-
+








-
+










-
+












-
+












-
+












-
+














-
+


-
+












-
+



-
+










-
+


-
+










-
+







    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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    set scrollInfo wrong
    .e insert 0 abcde
    .e insert 2 XXX
    vwait scrollInfo
    update
    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
    pack .e ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    set scrollInfo wrong
    .e insert 0 abcde
    .e insert 500 XXX
    vwait scrollInfo
    update
    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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    set scrollInfo wrong
    .e insert 0 abcde
    .e delete 2 4
    vwait scrollInfo
    update
    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
    pack .e ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    set scrollInfo wrong
    .e insert 0 abcde
    .e delete -1 2
    vwait scrollInfo
    update
    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
    pack .e ; update idletasks
    focus .e
} -body {
    .e configure -textvariable contents -xscrollcommand scroll
    update
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    set scrollInfo wrong
    .e insert 0 abcde
    .e delete 3 1000
    vwait scrollInfo
    update
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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 {
test entry-8.18 {DeleteChars procedure} -setup {
    entry .e -width 0 -font {Courier -12} -highlightthickness 2 -bd 2
    pack .e
    pack .e ; update idletasks
    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
} -result {1}

test entry-9.1 {EntryValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace variable x w override
    trace add variable x write override
    entry .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
    trace remove variable x write 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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    update
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
} -body {
    .e configure -width 10 -font {Courier -12} -textvariable x
    pack .e
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
} -body {
    .e insert 0 abcdefg
    destroy .e
    update
} -cleanup {
    destroy .e
} -result {}
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
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







-
+
















-
+












-
+












-
+




















-
+


















-
+







} -cleanup {
    destroy .b
} -result {{} {}}


test entry-13.1 {GetEntryIndex procedure} -setup {
    entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
    pack .e
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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
    pack .e ; update idletasks
} -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]
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
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







-
+



















-
+

















-
+


















-
+
















-
+



















-
+



















-
+









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
	pack .e ; update idletasks
	.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
	pack .e ; update idletasks
	.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
	pack .e ; update idletasks
	.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
	pack .e ; update idletasks
	.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
	pack .e ; update idletasks
	.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
	pack .e ; update idletasks
	.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
	pack .e ; update idletasks
	.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:
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
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







-
+










-
+










-
+










-
+










-
+










-
+









-
+









-
+










-
+










-
+












-
+







} -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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    update
    list [.e index @7] [.e index @8]
} -cleanup {
    destroy .e
} -result {0 1}

# XXX Still need to write tests for EntryScanTo and EntrySelectTo.
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
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







-
+










-
+










-
+

















-
-
+
+


-
+



-




+
-
+


-
+



-




+
-
+


-
+



-









-
+
+

-
+







} -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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
	pack .e ; update idletasks
    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}}]
    update
    set scrollInfo wrong
    .e delete 0 end
    .e insert 0 123
    vwait scrollInfo
    update
    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
    update
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    set scrollInfo wrong
    .e insert 0 0123456789abcdef
    .e xview 3
    vwait scrollInfo
    update
    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
    update
    set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
    set scrollInfo wrong
    .e insert 0 abcdefghijklmnopqrs
    .e xview 6
    vwait scrollInfo
    update
    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
    update
    set scrollInfo wrong
    .e configure -xscrollcommand thisisnotacommand
    vwait x
    update
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
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
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







-
+














-
+















-
+















-
+















-
+















-
+
















-
+
















-
+


















-
+




















-
+

















-
+




















-
+

















-
+


















-
+


















-
+







    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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    .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
3321
3322
3323
3324
3325
3326
3327
3328

3329
3330
3331
3332
3333
3334
3335
3299
3300
3301
3302
3303
3304
3305

3306
3307
3308
3309
3310
3311
3312
3313







-
+







    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
    pack .e ; update idletasks
    .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
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
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







-
+

















-
+



















-
+







    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
    pack .e ; update idletasks
    .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
    pack .e ; update idletasks
    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
    pack .e ; update idletasks
    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
3405
3406
3407
3408
3409
3410
3411
3412

3413
3414
3415
3416
3417
3418
3419
3383
3384
3385
3386
3387
3388
3389

3390
3391
3392
3393
3394
3395
3396
3397







-
+







    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
    pack .e ; update idletasks
    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
3428
3429
3430
3431
3432
3433
3434
3435

3436
3437
3438
3439
3440
3441
3442
3406
3407
3408
3409
3410
3411
3412

3413
3414
3415
3416
3417
3418
3419
3420







-
+







## 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
    pack .e ; update idletasks
    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}}

3502
3503
3504
3505
3506
3507
3508
3509

3510
3511
3512
3513
3514
3515
3516
3480
3481
3482
3483
3484
3485
3486

3487
3488
3489
3490
3491
3492
3493
3494







-
+







    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}
	    -validatecommand {%W configure -bg white; format 1}
    bind .e <Destroy> { set FOO hello }
    destroy .e
    winfo exists .e
} -cleanup {
    destroy .e
} -result 0

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
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







-
+










-
-
-
-
+
+
+
+




-
+







-
-
+
+








-
+







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}
} -match glob -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}]
} -match glob -result [list "a bmo" ::test::foo \
	{can*t set "::test::foo": parent namespace does*t exist} \
	{can*t set "::test::foo": parent namespace does*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
    trace add variable myvar write 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!}]
} -match glob -result [list {ca*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}
} -match glob -result {can*t trace "thisnsdoesntexist::myvar": parent namespace does*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 {}
3598
3599
3600
3601
3602
3603
3604



















3605
3606
3607
3608
3609
3610
3611
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    }}}
    pack .b
    bind .b <Configure> {unset -nocomplain var}
    update
    destroy .b
    unset new
} {}
test entry-25.3 {Bug [2a32225cd1] - Navigation in a password made of several words} -setup {
    destroy .e
    pack [entry .e -show *]
    update
    set res {}
} -body {
    .e insert end "A sample password made of several words"
    .e icursor end
    event generate .e <<PrevWord>>  ; # shall move insert to index 0
    .e delete insert end
    lappend res [.e get]
    .e insert end "A sample password made of several words"
    .e icursor 2
    event generate .e <<NextWord>>  ; # shall move insert to index end
    .e delete 0 insert
    lappend res [.e get]
} -cleanup {
    destroy .e
} -result {{} {}}


# 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.
Changes to tests/event.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
1
2
3



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


27
28
29
30
31
32
33
34


35
36
37
38
39
40
41
42


43
44
45
46
47
48








49
50
51
52
53
54
55
56






57
58
59
60
61








62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100

101
102
103
104

105
106
107
108

109
110

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130

131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177

178
179
180

181
182
183
184
185
186
187
188



-
-
-
+
+
+




















-
-
+
+






-
-
+
+






-
-
+
+




-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+



+
+










+







-
-
+
+







-
+



-
+



-
+

-
+














-
+




-
+









-
+









-
+















-
+










-
+


-
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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.

proc _init_keypress_lookup {} {
    global keypress_lookup

    scan A %c start
    scan Z %c finish

    for {set i $start} {$i <= $finish} {incr i} {
        set l [format %c $i]
        set keypress_lookup($l) $l
	set l [format %c $i]
	set keypress_lookup($l) $l
    }

    scan a %c start
    scan z %c finish

    for {set i $start} {$i <= $finish} {incr i} {
        set l [format %c $i]
        set keypress_lookup($l) $l
	set l [format %c $i]
	set keypress_lookup($l) $l
    }

    scan 0 %c start
    scan 9 %c finish

    for {set i $start} {$i <= $finish} {incr i} {
        set l [format %c $i]
        set keypress_lookup($l) $l
	set l [format %c $i]
	set keypress_lookup($l) $l
    }

    # Most punctuation
    array set keypress_lookup {
        ! exclam
        % percent
        & ampersand
        ( parenleft
        ) parenright
        * asterisk
        + plus
        , comma
	! exclam
	% percent
	& ampersand
	( parenleft
	) parenright
	* asterisk
	+ plus
	, comma
        - minus
        . period
        / slash
        : colon
        < less
        = equal
	. period
	/ slash
	: colon
	< less
	= equal
        > greater
        ? question
        @ at
        ^ asciicircum
        _ underscore
        | bar
        ~ asciitilde
        ' apostrophe
	? question
	@ at
	^ asciicircum
	_ underscore
	| bar
	~ asciitilde
	' apostrophe
    }
    # Characters with meaning to Tcl...
    array set keypress_lookup [list \
	    -    minus \
	    >    greater \
	    \"   quotedbl \
	    \#   numbersign \
	    \$   dollar \
	    \;   semicolon \
	    \[   bracketleft \
	    \\   backslash \
	    \]   bracketright \
	    \{   braceleft \
	    \}   braceright \
	    " "  space \
	    \xA0 nobreakspace \
	    "\n" Return \
	    "\t" Tab]
}

# Lookup an event in the keypress table.
# For example:
# Q -> Q
# . -> period
# / -> slash
# ; -> semicolon
# > -> greater
# Delete -> Delete
# Escape -> Escape

proc _keypress_lookup {char} {
    global keypress_lookup

    if {! [info exists keypress_lookup]} {
        _init_keypress_lookup
	_init_keypress_lookup
    }

    if {$char == ""} {
        error "empty char"
	error "empty char"
    }

    if {[info exists keypress_lookup($char)]} {
        return $keypress_lookup($char)
	return $keypress_lookup($char)
    } else {
        return $char
	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
	focus -force $win
    }
    event generate $win <Key-$keysym>
    _pause 50
    if {[focus] != $win} {
        focus -force $win
	focus -force $win
    }
    event generate $win <KeyRelease-$keysym>
    _pause 50
}

# Call _keypress for each character in the given string

proc _keypress_string {win string} {
    foreach letter [split $string ""] {
        _keypress $win $letter
	_keypress $win $letter
    }
}

# Delay script execution for a given amount of time

proc _pause {{msecs 1000}} {
    global _pause

    if {! [info exists _pause(number)]} {
        set _pause(number) 0
	set _pause(number) 0
    }

    set num [incr _pause(number)]
    set _pause($num) 0

    after $msecs "set _pause($num) 1"
    vwait _pause($num)
    unset _pause($num)
}

# Helper proc to convert index to x y position

proc _text_ind_to_x_y {text ind} {
    set bbox [$text bbox $ind]
    if {[llength $bbox] != 4} {
        error "got bbox \{$bbox\} from $text, index $ind"
	error "got bbox \{$bbox\} from $text, index $ind"
    }
    foreach {x1 y1 width height} $bbox break
    set middle_y [expr {$y1 + ($height / 2)}]
    return [list $x1 $middle_y]
}

# Return selection only if owned by the given widget

proc _get_selection {widget} {
    if {[string compare $widget [selection own]] != 0} {
        return ""
	return ""
    }
    if {[catch {selection get} sel]} {
        return ""
	return ""
    }
    return $sel
}

# Begining of the actual tests

test event-1.1 {Tk_HandleEvent procedure, filter events for dead windows} -setup {
251
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274




275
276
277
278
279
280
281
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267
268
269
270
271




272
273
274
275
276
277
278
279
280
281
282







-
+












-
-
-
-
+
+
+
+







    _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 {
	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>
	_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
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328




329
330
331
332
333
334
335
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326




327
328
329
330
331
332
333
334
335
336
337







+











-
-
-
-
+
+
+
+







    $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
	update idletasks
} -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>
	_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
360
361
362
363
364
365
366
367
368
369
370




371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390




391
392
393
394
395
396
397
362
363
364
365
366
367
368




369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388




389
390
391
392
393
394
395
396
397
398
399







-
-
-
-
+
+
+
+
















-
-
-
-
+
+
+
+







    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Now drag until selend is highlighted, then click up

    set current $anchor
    while {[$e compare $current <= $selend]} {
        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
	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]

    # 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
	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]
427
428
429
430
431
432
433
434
435
436
437




438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457




458
459
460
461
462
463
464
429
430
431
432
433
434
435




436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455




456
457
458
459
460
461
462
463
464
465
466







-
-
-
-
+
+
+
+
















-
-
-
-
+
+
+
+







    # Save the position of the insert cursor
    lappend result [$e index insert]

    # Now drag until selend is highlighted, then click up

    set current $anchor
    while {$current <= $selend} {
        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
        _pause 50
	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
	_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]

    # 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
	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]
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625







-
+








    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 {
	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"
666
667
668
669
670
671
672
673

674
675
676
677
678



679
680
681
682
683
684
685
668
669
670
671
672
673
674

675
676
677



678
679
680
681
682
683
684
685
686
687







-
+


-
-
-
+
+
+








    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"]
	"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 {
	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]
752
753
754
755
756
757
758

759
760
761
762
763
764
765
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768







+








    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows
    unset x1 y1 width height middle_y left_x left_y right_x right_y
} -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]
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
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







+



-
-
+
+




















-
-
-
+
+
+

-
-
-
+
+
+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








    lappend result [$e index insert]
    lappend result [_get_selection $e]

    return $result
} -cleanup {
    deleteWindows
    unset x1 y1 width height middle_y left_x left_y right_x right_y
} -result {4 A 4 A}

test event-8 {event generate with keysyms corresponding to
              multi-byte virtual keycodes - bug
              e36963bfe8df9f5e528134707a91b9c0051de723} -constraints nonPortable -setup {
	      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"
    if {[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."
	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}

test event-9.1 {enter . window by destroying a toplevel - bug b1d115fa60} -setup {
    set EnterBind [bind . <Enter>]
} -body {
    wm geometry . 200x200+300+300
    wm deiconify .
    _pause 200
    toplevel .top2 -width 200 -height 200
    wm geometry .top2 +[expr {[winfo rootx .]+50}]+[expr {[winfo rooty .]+50}]
    _pause 200
    wm deiconify .top2
    raise .top2
    _pause 400
    event generate .top2 <Motion> -warp 1 -x 50 -y 50
    _pause 100
    bind . <Enter> {lappend res %W}
    set res [list ]
    destroy .top2
    _pause 200
    set res
} -cleanup {
    deleteWindows
    bind . <Enter> $EnterBind
} -result {.}
test event-9.2 {enter toplevel window by destroying a toplevel - bug b1d115fa60} -setup {
    set iconified false
    if {[winfo ismapped .]} {
	wm iconify .
	update
	set iconified true
    }
} -body {
    toplevel .top1
    wm geometry .top1 200x200+300+300
    wm deiconify .top1
    _pause 200
    toplevel .top2 -width 200 -height 200
    _pause 200
    wm geometry .top2 +[expr {[winfo rootx .top1]+50}]+[expr {[winfo rooty .top1]+50}]
    _pause 200
    wm deiconify .top2
    raise .top2
    _pause 400
    event generate .top2 <Motion> -warp 1 -x 50 -y 50
    _pause 100
    bind .top1 <Enter> {lappend res %W}
    set res [list ]
    destroy .top2
    _pause 200
    set res
} -cleanup {
    deleteWindows ; # destroy all children of ".", this already includes .top1
    if {$iconified} {
	wm deiconify .
	update
    }
} -result {.top1}

# cleanup
update
unset -nocomplain keypress_lookup
rename _init_keypress_lookup {}
rename _keypress_lookup {}
rename _keypress {}
Changes to tests/filebox.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
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.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
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 <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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102







-


















-
+







    }

    update
    SendButtonPress $parent ok mouse
}

proc SendButtonPress {parent btn type} {
    global tk_strictMotif
    if {$parent == "."} {
	set w .__tk_filedialog
    } else {
	set w $parent.__tk_filedialog
    }
    upvar ::tk::dialog::file::__tk_filedialog 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
	event generate $w <KeyPress> -keysym Return
    }
}


#----------------------------------------------------------------------
#
# The test suite proper
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
205
206
207
208
209
210
211

212
213
214
215
216
217
218







-







    set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring

    set color #404040
    test filebox-2.1-$mode "tk_getOpenFile command" nonUnixUserInteraction {
        ToPressButton $parent cancel
        tk_getOpenFile -title "Press Cancel ($verylongstring)" -parent $parent
    } ""

    set fileName $tmpFile
    set fileDir [tcltest::temporaryDirectory]
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
275
276
277
278
279
280
281



282
283
284
285
286
287
288







-
-
-







    }
    foreach {x res} [list 1 "-unset-" 2 "Text files"] {
	set t [expr {$x + [llength [array names filters]]}]
        test filebox-3.$t-$mode "tk_getOpenFile command" nonUnixUserInteraction {
	    catch {unset tv}
	    catch {unset typeName}
	    ToPressButton $parent ok
	    if {[info exists tv]} {
	    } 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 {
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
328
329
330
331
332
333
334














335
336
337
338
339
340
341







-
-
-
-
-
-
-
-
-
-
-
-
-
-







    } -returnCodes error -result {bad file type "Foo", should be "typeName {extension ?extensions ...?} ?{macType ?macTypes ...?}?"}

    set isNative [expr {
	[info commands ::tk::MotifFDialog] eq "" &&
	[info commands ::tk::dialog::file::] eq ""
    }]

    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
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring
    # set verylongstring $verylongstring$verylongstring

    set color #404040
    test filebox-5.1-$mode "tk_getSaveFile command" nonUnixUserInteraction {
	ToPressButton $parent cancel
	tk_getSaveFile -title "Press Cancel ($verylongstring)" -parent $parent
    } ""

    set fileName "12x 455"
    set fileDir [pwd]
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
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 "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.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
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} {
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88







-
+










+







update
bind all <FocusIn> {
    append focusInfo "in %W %d\n"
}
bind all <FocusOut> {
    append focusInfo "out %W %d\n"
}
bind all <Key> {
bind all <KeyPress> {
    append focusInfo "press %W %K"
}
focusSetup
if {[testConstraint altDisplay]} {
    focusSetupAlt
}


test focus-1.1 {Tk_FocusCmd procedure} -constraints unix -body {
    focusClear
    after 100
    focus
} -result {}
test focus-1.2 {Tk_FocusCmd procedure} -constraints {
	unix altDisplay
} -body {
    focus .alt.b
    focus
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330







-
+







} -body {
    focus .t.b1
    focus .
    update
    event gen [testwrapper .t] <FocusIn> -detail NotifyAncestor
    set focusInfo {}
    set x [focus]
    event gen . <x>
    event gen . <KeyPress-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
616
617
618
619
620
621
622
623

624
625
626
627
628
629
630
617
618
619
620
621
622
623

624
625
626
627
628
629
630
631







-
+







    lappend result [focus]
} -cleanup {
    cleanupbg
} -result {.t {} {}}
destroy .t
bind all <FocusIn> {}
bind all <FocusOut> {}
bind all <Key> {}
bind all <KeyPress> {}


fixfocus
test focus-6.1 {miscellaneous - embedded application in same process} -constraints {
    unix  testwrapper
} -setup {
    eval interp delete [interp slaves]
750
751
752
753
754
755
756























757
758
759
760
761
762
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






    focus -force .top.s3
    update
    focus
} -cleanup {
    destroy .top
} -result {.top.s3}

test focus-8.1 {fdc0ed342d - segfault on focus -force} -body {
    pack [button .b0]
    toplevel .one
    update
    event generate .one <Motion> -warp 1 -x 175 -y 175
    update idletasks
    destroy {*}[winfo children .]
    toplevel .t
    pack [canvas .t.c]
    update
    destroy .t.c
    pack [label .t.l]
    update
    destroy .t.l
    destroy {*}[winfo children .]
    proc crashit {} {
	pack [listbox .l]
	update
	focus -force .l;  # This line segfaulted *with xvfb*
	set res Reached
    }
    crashit
} -result {Reached}

deleteWindows

# cleanup
cleanupTests
return
Changes to tests/focusTcl.test.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
1
2
3
4
5


6
7
8
9
10
11
12
13
14





-
-
+
+







# 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.
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

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
1
2
3
4


5
6
7
8
9
10
11
12
13
14
15


16
17

18
19
20
21
22
23
24



25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52




-
-
+
+









-
-
+
+
-







-
-
-
+
+
+






-
+










-
+







# 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.
# Copyright (c) 1996-1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
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
        }
	if {$afont ni $defaultfontlist} {
	    lappend nondeffonts $afont
	}
    }
    set nondeffonts
}

proc clearnondefaultfonts {} {
    foreach afont [getnondefaultfonts] {
        font delete $afont
	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"}
    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 ""}} {
112
113
114
115
116
117
118
119

120
121
122
123

124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154

155
156
157

158
159

160
161

162
163

164
165
166
167

168
169
170
171
172
173
174
111
112
113
114
115
116
117

118
119
120
121

122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152

153
154
155

156
157

158
159

160
161

162
163
164
165

166
167
168
169
170
171
172
173







-
+



-
+









-
+















-
+




-
+


-
+

-
+

-
+

-
+



-
+







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?"}
} -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?"}
} -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?"}
} -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}
} -result {Times New Roman}
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
    font actual {-family times} -- \ud800
} -match glob -result {*}
test font-4.13 {font command: actual} -body {
    font actual {-family times} -- \uDC00
    font actual {-family times} -- \udc00
} -match glob -result {*}
test font-4.14 {font command: actual} -constraints {utfcompat win} -body {
test font-4.14 {font command: actual} -constraints win -body {
    font actual {-family times} -family -- \uD800\uDC00
} -result {times}
} -result {Times New Roman}
test font-4.15 {font command: actual} -body {
    font actual {-family times} -- \uDC00\uD800
    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}
} -result {Times New Roman}


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 {
428
429
430
431
432
433
434
435

436
437
438
439

440
441
442
443
444
445
446
427
428
429
430
431
432
433

434
435
436
437

438
439
440
441
442
443
444
445







-
+



-
+







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?"}
} -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?"}
} -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"
519
520
521
522
523
524
525
526

527
528
529
530
531

532
533
534
535

536
537
538
539
540
541
542
518
519
520
521
522
523
524

525
526
527
528
529

530
531
532
533

534
535
536
537
538
539
540
541







-
+




-
+



-
+







} -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
    update idletasks
} -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
    update idletasks
    set b1 [winfo reqwidth .t.f]
    font configure xyz -family helvetica -size 20
    set a2 [font measure xyz "abcd"]
    update
    update idletasks
    set b2 [winfo reqwidth .t.f]
    expr {$a1==$b1 && $a2==$b2}
} -cleanup {
    destroy .t.f
    font delete xyz
} -result 1

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
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







-
+



-
+

+








-
+


-
+

-
+

+








-
+

-
+


-
+

+









test font-15.1 {Tk_AllocFontFromObj - converting internal reps} -constraints {
    testfont
} -setup {
    destroy .b1 .b2
} -body {
    set x {Times 16}
    set x [font create font-15.1_font -family Times -size 16]
    lindex $x 0
    button .b1 -font $x
    lindex $x 0
    testfont counts {Times 16}
    testfont counts $x
} -cleanup {
    font delete font-15.1_font
    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}
    set x [font create font-15.2_font -family Times -size 16]
    button .b1 -font $x
    destroy .b1
    lappend result [testfont counts {Times 16}]
    lappend result [testfont counts $x]
    button .b2 -font $x
    lappend result [testfont counts {Times 16}]
    lappend result [testfont counts $x]
} -cleanup {
    font delete font-15.2_font
    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}
    set x [font create font-15.3_font -family Times -size 16]
    button .b1 -font $x
    lappend result [testfont counts {Times 16}]
    lappend result [testfont counts $x]
    button .b2 -font $x
    pack .b1 .b2 -side top
    lappend result [testfont counts {Times 16}]
    lappend result [testfont counts $x]
} -cleanup {
    font delete font-15.3_font
    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 {
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
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







-
+




-
+



-
+

-
+

-
+

-
+
+
+







    .t.f cget -font
} -cleanup {
    destroy .t.f
} -result {-family fixed}


test font-17.1 {Tk_FreeFontFromObj - reference counts} -constraints {
	testfont
    testfont
} -setup {
    destroy .b1 .b2 .b3
    set result {}
} -body {
    set x {Courier 12}
    set x [font create font-17.1_font -family Courier -size 12]
    button .b1 -font $x
    button .b3 -font $x
    button .b2 -font $x
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts $x]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts $x]
    destroy .b2
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts $x]
    destroy .b3
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts $x]
} -cleanup {
    font delete font-17.1_font
} -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)
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
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







+
-
+

-
+

-
+

-
+

-
+

-
+

-
+


+
+







} -result {-family -family}


test font-18.1 {FreeFontObjProc} -constraints testfont -setup {
    destroy .b1
    set result {}
} -body {
    set f [font create font-18.1_font -family Courier -size 12]
    set x [join {Courier 12} { }]
    set x [join [list $f 50] { }]
    button .b1 -font $x
    set y [join {Courier 12} { }]
    set y [join [list $f 50] { }]
    .b1 configure -font $y
    set z [join {Courier 12} { }]
    set z [join [list $f 50] { }]
    .b1 configure -font $z
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts [list $f 50]]
    set x red
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts [list $f 50]]
    set z 32
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts [list $f 50]]
    destroy .b1
    lappend result [testfont counts {Courier 12}]
    lappend result [testfont counts [list $f 50]]
    set y bogus
    return $result
} -cleanup {
    font delete font-18.1_font
} -result {{{1 3}} {{1 2}} {{1 1}} {}}


test font-19.1 {Tk_FontId} -setup {
    destroy .t.f
    pack [label .t.f]
    update
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
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







-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+








-
+

-
+







-
+

-
+







-
+

-
+







-
+

-
+







} -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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-Book
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-Demi
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-BookOblique
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x AvantGarde-DemiOblique
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-Light
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-Demi
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-LightItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Bookman-DemiItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier-Bold
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier-Oblique
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Courier-BoldOblique
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica-Bold
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica-Oblique
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Helvetica-BoldOblique
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-Roman
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-Bold
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-Italic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x NewCenturySchlbk-BoldItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-Roman
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-Bold
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-Italic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Palatino-BoldItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Symbol
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-Roman
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-Bold
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-Italic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x Times-BoldItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfChancery-MediumItalic
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfDingbats
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfDingbats
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfDingbats
	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]
	set x [psfontname avantgarde 12 roman normal]
    } else {
        set x ZapfDingbats
	set x ZapfDingbats
    }
} -result {ZapfDingbats}

test font-21.47 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    win
} -body {
    set x [psfontname {arial 12 roman normal}]
2254
2255
2256
2257
2258
2259
2260
2261

2262
2263
2264
2265
2266
2267
2268
2261
2262
2263
2264
2265
2266
2267

2268
2269
2270
2271
2272
2273
2274
2275







-
+







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
    unixOrWin haveTimes12BoldItalicUnderlineOverstrikeFont
} -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 {
2294
2295
2296
2297
2298
2299
2300
2301

2302
2303
2304
2305
2306
2307
2308
2301
2302
2303
2304
2305
2306
2307

2308
2309
2310
2311
2312
2313
2314
2315







-
+







    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
	-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 {}
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
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







-
+


+

-
+


-
-
+
+







+
+
+
+
+
+
+







-
-
+
+

-
-
+
+

-
-
+
+







    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 {
test font-44.1 {TkFontGetPixels: size < 0}  -setup {
    set oldscale [tk scaling]
} -body {
    # if this test failed, start the investigations by reading ticket [8162e9b7a9]
    tk scaling 0.5
    font actual {times -12} -size
    font actual {times -13} -size
} -cleanup {
    tk scaling $oldscale
} -result 24
test font-44.2 {TkFontGetPoints: size >= 0} -constraints {noExceed failsOnUbuntuNoXft} -setup {
} -result 26
test font-44.2 {TkFontGetPoints: size >= 0} -constraints {noExceed haveTimes12Font} -setup {
    set oldscale [tk scaling]
} -body {
    tk scaling 0.5
    font actual {times 12} -size
} -cleanup {
    tk scaling $oldscale
} -result 12
test font-44.3 {font create with display scaling not 100% - bug 8162e9b7a9} -body {
    set font1 TkDefaultFont
    set font2 [font create Font2 {*}[font actual $font1]]
    expr {[font actual $font1 -size] == [font actual $font2 -size]}
} -cleanup {
    font delete $font2
} -result 1


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 {
} -result {Times New Roman}
test font-45.3 {TkFontGetAliasList: match} -constraints {noExceed failsOnUbuntu} -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
	# 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]} ]
	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 *\
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








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    load {} Tk one
    load {} Tk two
    one eval menu .menubar
    two eval menu .menubar
    interp delete one
    interp delete two
} -result {}

test font-47.2 {Bug 3049518 - Canvas} -body {
    if {"MyFont" ni [font names]} {
	font create MyFont -family "Liberation Sans" -size 13
    }
    set text Hello!
    destroy .t.c
    set c [canvas .t.c]
    set textid [$c create text 20 20 -font MyFont -text $text -anchor nw]
    set twidth [font measure MyFont $text]
    set theight [font metrics MyFont -linespace]
    set circid [$c create polygon \
	15                    15 \
	[expr {15 + $twidth}] 15 \
	[expr {15 + $twidth}] [expr {15 + $theight}] \
	15                    [expr {15 + $theight}] \
	    -width 1 -joinstyle round -smooth true -fill {} -outline blue]
    pack $c -fill both -expand 1 -side top
    update

    # Lambda test functions
    set circle_text {{w user_data text circ} {
	if {[winfo class $w] ne "Canvas"} {
	    puts "Wrong widget type: $w"
	    return
	}
	if {$user_data ne "FontChanged"} {
	    return
	}
	lappend ::results called-$w
	lassign [$w bbox $text] x0 y0 x1 y1
	set offset 5
	set coord [lmap expr {
			      $x0-$offset $y0-$offset $x1+$offset $y0-$offset
			      $x1+$offset $y1+$offset $x0-$offset $y1+$offset
			  } {expr $expr}]
	if {[catch {$w coord $circ $coord} err]} {
	    puts Error:$err
	}
    }}
    set enclosed {{can id} {$can find enclosed {*}[$can bbox $id]}}

    set results {}
    apply $circle_text $c FontChanged $textid $circid
    update
    bind $c <<TkWorldChanged>> [list apply $circle_text %W %d $textid $circid]

    # Begin test:
    set results {}
    lappend results [apply $enclosed $c $circid]
    font configure MyFont -size 26
    update  ; # services the "TheWorldHasChanged" event, queues "TkWorldChanged" events
    update  ; # services the queued "TkWorldChanged" events
    lappend results [apply $enclosed $c $circid]
    font configure MyFont -size 9
    update idletasks
    update
    lappend results [apply $enclosed $c $circid]
    font configure MyFont -size 12
    update idletasks
    update
    lappend results [apply $enclosed $c $circid]
} -cleanup {
    destroy $c
    unset -nocomplain ::results
} -result {{1 2} called-.t.c {1 2} called-.t.c {1 2} called-.t.c {1 2}}

test font-47.3 {Bug 3049518 - Label} -body {
    if {"MyFont" ni [font names]} {
	font create MyFont -family "Liberation Sans" -size 13
    }
    set text "Label Test"
    destroy .t.l

    set make-img {{size} {
	set img [image create photo -width $size -height $size]
	$img blank
	set max [expr {$size - 1}]
	for {set x 0} {$x < $size} {incr x} {
	    $img put red -to $x $x
	    $img put black -to 0 $x
	    $img put black -to $x 0
	    $img put black -to $max $x
	    $img put black -to $x $max
	}
	return $img
    }}

    set testWorldChanged {{w user_data} {
	global make-img
	if {$user_data ne "FontChanged"} {
	    return
	}
	if {![winfo exists $w] || [winfo class $w] ne "Label"} {
	    return
	}
	if {[$w cget -image] ne ""} {
	    image delete [$w cget -image]
	}
	set size [font metrics [$w cget -font] -linespace]
	set img [apply ${make-img} $size]
	$w configure -image $img
    }}

    set check {{w} {
	global results
	set f [$w cget -font]
	set i [$w cget -image]
	set fs [font metrics $f -linespace]
	set ish [image height $i]
	set isw [image width $i]
	lappend results [list [expr {$fs == $ish ? 1 : [list $fs $ish]}] [expr {$fs == $isw ? 1 : [list $fs $isw]}]]
    }}

    set size [font metrics MyFont -linespace]
    set img [apply ${make-img} $size]
    set l [label .t.l -compound left -image $img -text $text -font MyFont]
    pack $l -side top -fill both -expand 1
    update
    bind $l <<TkWorldChanged>> [list apply $testWorldChanged %W %d]
    set ::results {}

    apply $check $l
    font configure MyFont -size 26
    update  ; # services the "TheWorldHasChanged" event, queues "TkWorldChanged" events
    update  ; # services the queued "TkWorldChanged" events
    apply $check $l
    font configure MyFont -size 9
    update idletasks
    update
    apply $check $l
    font configure MyFont -size 13
    update idletasks
    update
    apply $check $l
    set results
} -cleanup {
    destroy $l
    unset -nocomplain ::results
} -result {{1 1} {1 1} {1 1} {1 1}}

# cleanup
cleanupTests
return




Changes to tests/fontchooser.test.
1
2
3

4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2

3
4
5
6
7
8



9
10

11
12
13
14
15
16
17
18


-
+





-
-
-


-
+







# Test the "tk::fontchooser" command
#
# Copyright © 2008 Pat Thoyts
# Copyright (c) 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).
# dialog (hence the weirdness).

proc start {cmd} {
    set ::tk_dialog {}
    set ::iter_after 0
    after 1 $cmd
}
proc then {cmd} {
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+







-
+







    }
    set x
} -result {Hello}

test fontchooser-2.1 {fontchooser -title (cyrillic)} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure \
            -title "Привет"
            -title "\u041f\u0440\u0438\u0432\u0435\u0442"
        tk::fontchooser::Show
    }
    then {
        set x [wm title $::tk_dialog]
        Click cancel
    }
    set x
} -result "Привет"
} -result "\u041f\u0440\u0438\u0432\u0435\u0442"

test fontchooser-3.0 {fontchooser -parent} -constraints scriptImpl -body {
    start {
        tk::fontchooser::Configure -parent .
        tk::fontchooser::Show
    }
    then {
178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193
194






195
196
197
198
199
200
201
202
203
204
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207







-
+









+
+
+
+
+
+










    }
    then {
        Click ok
    }
    expr {$::testfont ne {}}
} -result 1

test fontchooser-4.4 {fontchooser -font} -constraints {scriptImpl failsOnUbuntuNoXft} -body {
test fontchooser-4.4 {fontchooser -font} -constraints {scriptImpl haveTimes14BoldFont} -body {
    start {
        tk::fontchooser::Configure -command ApplyFont -font {times 14 bold}
        tk::fontchooser::Show
    }
    then {
        Click ok
    }
    lrange $::testfont 1 end
} -result {14 bold}

test fontchooser-5.1 {fontchooser multiple configure} -constraints {scriptImpl} -body {
    tk fontchooser configure -title TestTitle -command foo
    tk fontchooser configure -command bar
    tk fontchooser configure -title
} -result {TestTitle}

# -------------------------------------------------------------------------

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


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 "frame", "labelframe" and
# "toplevel" commands of Tk.  It is organized in the standard fashion for Tcl
# 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 © 1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
eval 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.
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86







-
+







# 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
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183







-
+







    frame .f
    set opts {}
    foreach opt [.f configure] {
        if {[llength $opt] == 5} {
            lappend opts [lindex $opt 0] [lindex $opt 4]
        }
    }
    frame .g {*}$opts
    eval frame .g $opts
} -cleanup {
    destroy .f .g
    deleteWindows
} -result .g

destroy .f
frame .f
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490







-
+







    # 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
    eval toplevel .g $opts
} -cleanup {
    destroy .f .g
    deleteWindows
} -result .g

destroy .t
toplevel .t -width 300 -height 150
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
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







-
-
-
-
-
-









-
-
-
-
+
-


-
-
-
-
-
+
+
-







    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
    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
    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}
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
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







-
+














-
+







    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}
} -result {-background -bd -bg -borderwidth -class -colormap -container -cursor -height -highlightbackground -highlightcolor -highlightthickness -padx -pady -relief -takefocus -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}
} -result {-background -bd -bg -borderwidth -class -colormap -container -cursor -height -highlightbackground -highlightcolor -highlightthickness -menu -padx -pady -relief -screen -takefocus -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]
1024
1025
1026
1027
1028
1029
1030
1031

1032
1033
1034
1035
1036
1037
1038
1010
1011
1012
1013
1014
1015
1016

1017
1018
1019
1020
1021
1022
1023
1024







-
+








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
    update
    lappend result [winfo ismapped .t]
} -cleanup {
    deleteWindows
} -result {0 1}
test frame-9.2 {MapFrame procedure} -setup {
    deleteWindows
} -body {
1049
1050
1051
1052
1053
1054
1055
1056

1057
1058
1059
1060
1061
1062
1063
1035
1036
1037
1038
1039
1040
1041

1042
1043
1044
1045
1046
1047
1048
1049







-
+







    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
    update
    winfo exists .t
} -cleanup {
    deleteWindows
} -result 0

test frame-10.1 {frame widget vs hidden commands} -setup {
    deleteWindows
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
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







-






-
-
-
-
+
-



-
-
+
-
-
+
-







    }
    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
    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
    update  ; # services the "TheWorldHasChanged" event, queues "TkWorldChanged" events
    } else {
	update
    update  ; # services the queued "TkWorldChanged" events
    }
    set h2 [font metrics myfont -linespace]
    set y2 [winfo y .f.f]
    expr {($h2 - $h1) - ($y2 - $y1)}
} -cleanup {
    deleteWindows
    font delete myfont
} -result 0
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
1481
1482
1483
1484
1485
1486
1487




























































































































































































































































































1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











    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:
Changes to tests/geometry.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

proc getsize w {
    regexp {(^[^+-]*)} [wm geometry $w] foo x
    return $x
}

Changes to tests/get.test.
1
2
3
4
5
6


7
8
9
10
11
12
13
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1998 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107







-
+







} -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}
} -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
126
127
128
129
130
131
132
133

134
135
136
137
138
126
127
128
129
130
131
132

133
134
135
136
137
138







-
+





} -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}
} -returnCodes error -result {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
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







# 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.
# Copyright (c) 1998-2000 Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

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
1
2
3


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33



-
-
+
+




















-
+







# 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.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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]
    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 ""
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69

70
71
72
73
74
75
76
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

66
67
68

69
70
71
72
73
74
75
76







-
+

















-
+


-
+







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}
} -returnCodes error -result {bad option "foo": must be anchor, bbox, columnconfigure, configure, content, forget, info, location, propagate, remove, rowconfigure, size, or slaves}
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}
} -returnCodes error -result {can't determine master window}
test grid-1.7 {basic argument checking} -body {
    grid configure x
} -returnCodes error -result {can't determine container window}
} -returnCodes error -result {can't determine master 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 {
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103







-
+







    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??"}
} -returnCodes error -result {wrong # args: should be "grid bbox master ?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 {
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189







-
+







} -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 "."}
} -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}
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226







-
+









-
+







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}
} -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}
} -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]
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303







-
+







    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"}
} -returnCodes error -result {wrong # args: should be "grid location master 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 {
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
362
363
364
365
366
367
368

369


370
371
372
373
374
375
376







-
+
-
-







	    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 {
test grid-6.9 {location: check updates pending} -body {
    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
572
573
574
575
576
577
578
579

580
581
582
583
584

585
586
587
588
589
590
591
570
571
572
573
574
575
576

577
578
579
580
581

582
583
584
585
586
587
588
589







-
+




-
+







} -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 ...?"}
} -returnCodes error -result {wrong # args: should be "grid columnconfigure master 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 ...?"}
} -returnCodes error -result {wrong # args: should be "grid columnconfigure master 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
852
853
854
855
856
857
858
859

860
861
862
863
864
865

866
867
868
869
870
871
872
850
851
852
853
854
855
856

857
858
859
860
861
862

863
864
865
866
867
868
869
870







-
+





-
+







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}
} -returnCodes error -result {can't use '^', cant find master}
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 "^"}
} -returnCodes error -result {can't find slave 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 {
913
914
915
916
917
918
919
920

921
922
923
924
925
926
927
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925







-
+







} -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 "^"}
} -returnCodes error -result {can't find slave 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
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169
1170







-
+







} -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"}
} -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}
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
2035
2036
2037
2038
2039
2040
2041

2042



















































































































2043
2044
2045
2046
2047
2048
2049







-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    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:
Changes to tests/image.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
304
305
306
307
308
309
310

311


312
313
314
315
316
317
318







-
+
-
-







    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 {
test image-6.1 {Tk_ImageCmd procedure, "types" option} -body {
    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}


Changes to tests/imgBmap.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231







-
+







    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}}
} -result {1 {couldn't read bitmap file "~bad_user/a/b": no such file or directory}}
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 {
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
Changes to tests/imgPNG.test.
1
2
3
4
5
6
7
8




9
10
11
12
13
14
15
1
2
3
4




5
6
7
8
9
10
11
12
13
14
15




-
-
-
-
+
+
+
+







# 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
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 1998 Willem van Schaik (images only)
# Copyright (c) 2008 Donal K. Fellows
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
1109
1110
1111
1112
1113
1114
1115
1116
1117


1118

1119
1120
1121
1122
1123
1124
1125
1126
1127
1109
1110
1111
1112
1113
1114
1115


1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128







-
-
+
+

+









} -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

} -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
1
2
3
4


5
6
7
8
9
10
11
12
13




-
-
+
+







# 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.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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
1
2
3
4




5
6
7
8
9
10
11
12




































































13
14
15
16

17



18
19
20
21
22
23
24
25
26
27




-
-
-
-
+
+
+
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-
+
-
-
-
+
+
+







# 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
# Copyright (c) 1994 The Australian National University
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 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
#
# Used for 4.65 - 4.73 tests
# Now for some heftier testing, checking that setting and resetting of pixels'
# transparency status doesn't "leak" with any one-off errors.
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149

150
151
152
153
154
155

156
157
158
159
160
161
162
51
52
53
54
55
56
57

58






59
60
61
62
63
64
65
66
67
68
69
70

71
72
73

74
75
76
77
78
79

80
81
82
83
84
85
86
87







-

-
-
-
-
-
-












-
+


-
+





-
+







}

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 {
test imgPhoto-1.3 {options for photo images} -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 {
test imgPhoto-1.4 {options for photo images} -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 {
test imgPhoto-1.5 {options for photo images} -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 {
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
101
102
103
104
105
106
107

















108
109
110
111
112
113
114
115







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







} -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 {
215
216
217
218
219
220
221
222
223


224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
124
125
126
127
128
129
130


131
132


133
134
135
136
137

138


139
140
141
142
143
144

145


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160



































161
162
163
164
165
166
167
168







-
-
+
+
-
-





-
+
-
-






-
+
-
-















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







# 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 {

test imgPhoto-3.1 {ImgPhotoConfigureModel procedure} -body {
    hasTeapotPhoto
} -body {
    image create photo photo1 -file $teapotPhotoFile
    photo1 configure -file $teapotPhotoFile
} -cleanup {
    image delete photo1
} -result {}
test imgPhoto-3.2 {ImgPhotoConfigureModel procedure} -constraints {
test imgPhoto-3.2 {ImgPhotoConfigureModel procedure} -body {
    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 {
test imgPhoto-3.3 {ImgPhotoConfigureModel procedure} -setup {
    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 ...?"}
351
352
353
354
355
356
357
358

359
360
361
362
363
364
365
366
367
220
221
222
223
224
225
226

227


228
229
230
231
232
233
234







-
+
-
-







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 {
test imgPhoto-4.10 {ImgPhotoCmd procedure: copy option} -setup {
    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]
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
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
261
262
263
264
265
266
267

268


269
270
271
272
273
274
275
276
277

278


279
280
281
282
283
284
285
286

287


288
289
290
291
292
293
294
295

296


297
298
299
300
301
302
303
304

305


306
307
308
309
310
311
312
313

314


315
316
317
318
319
320
321
322

323


324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343


344


345
346


347
348


349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

369
370
371

372


373
374
375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392

393
394
395
396



397



398
399
400
401

402
403
404
405
406
407
408

409


410
411
412
413
414
415
416
417
418
419
420
421
422

423


424
425
426
427
428
429
430
431
432
433
434
435
436

437


438
439
440
441
442
443
444

445


446
447
448
449
450
451
452







-
+
-
-









-
+
-
-








-
+
-
-








-
+
-
-








-
+
-
-








-
+
-
-








-
+
-
-




















-
-
+
-
-


-
-
+
+
-
-


-
+

















-
+


-
+
-
-













-
+






-
+



-
-
-
+
-
-
-




-







-
+
-
-













-
+
-
-













-
+
-
-







-
+
-
-







    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 {
test imgPhoto-4.15 {ImgPhotoCmd procedure: copy option} -setup {
    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 {
test imgPhoto-4.16 {ImgPhotoCmd procedure: copy option} -setup {
    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 {
test imgPhoto-4.17 {ImgPhotoCmd procedure: copy option} -setup {
    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 {
test imgPhoto-4.18 {ImgPhotoCmd procedure: copy option} -setup {
    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 {
test imgPhoto-4.19 {ImgPhotoCmd procedure: copy option} -setup {
    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 {
test imgPhoto-4.20 {ImgPhotoCmd procedure: copy option} -setup {
    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 {
test imgPhoto-4.21 {ImgPhotoCmd procedure: copy option} -setup {
    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 {
test imgPhoto-4.22 {ImgPhotoCmd procedure: get option} -setup {
    hasTranspTeapotPhoto
} -setup {
    image create photo photo1
} -body {
    photo1 read $transpTeapotPhotoFile
    list [photo1 get 100 100 -withalpha] \
    photo1 read $teapotPhotoFile
    list [photo1 get 100 100] [photo1 get 150 100] [photo1 get 100 150]
	[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}}
} -result {{169 117 90} {172 115 84} {35 35 35}}
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
    photo1 get
} -cleanup {
    image delete photo1
} -returnCodes error -result \
} -returnCodes error -result {wrong # args: should be "photo1 get x y"}
    {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}
} -result {all elements of color list 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"}
} -returnCodes error -result {can't parse color "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}}
    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 {
test imgPhoto-4.31 {ImgPhotoCmd procedure: read option} -setup {
    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 {
test imgPhoto-4.33 {ImgPhotoCmd procedure: read option} -setup {
    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 {
test imgPhoto-4.35 {ImgPhotoCmd procedure: read option} -setup {
    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 {
test imgPhoto-4.36 {ImgPhotoCmd procedure: read option} -setup {
    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}}
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
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







-













-
+






-
+



-
+


-
+







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?"}
} -result {wrong # args: should be "photo1 transparency get x y"}
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?"}
} -result {wrong # args: should be "photo1 transparency get x y"}
test imgPhoto-4.43 {ImgPhotoCmd procedure: transparency get option} -setup {
    image create photo photo1
} -body {
    photo1 transparency get 0 0 0 -alpha
    photo1 transparency get 0 0 0
} -returnCodes error -cleanup {
    image delete photo1
} -result {wrong # args: should be "photo1 transparency get x y ?-option?"}
} -result {wrong # args: should be "photo1 transparency get x y"}
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"}
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
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







-






-
-
+






-
-
+






-
-
+



-
+


-
-
+
















-







} -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?"}
} -result {wrong # args: should be "photo1 transparency set x y boolean"}
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?"}
} -result {wrong # args: should be "photo1 transparency set x y boolean"}
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?"}
} -result {wrong # args: should be "photo1 transparency set x y boolean"}
test imgPhoto-4.55 {ImgPhotoCmd procedure: transparency set option} -setup {
    image create photo photo1
} -body {
    photo1 transparency set 0 0 0 0 -alpha
    photo1 transparency set 0 0 0 0
} -returnCodes error -cleanup {
    image delete photo1
} -result \
    {wrong # args: should be "photo1 transparency set x y newVal ?-option?"}
} -result {wrong # args: should be "photo1 transparency set x y boolean"}
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
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
650
651
652
653
654
655
656

657
658
659
660
661
662
663







-







} -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
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
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







-
+
-
-







-
+
-
-









-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-



















-
+













-
-
+
+
-
-












-
+
-
-







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 {
test imgPhoto-4.75 {<photo> read command: filename starting with '-'} -body {
    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 {
test imgPhoto-4.76 {ImgPhotoCmd procedure: copy to same image} -setup {
    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 {
test imgPhoto-5.1 {ImgPhotoGet/Free procedures, shared instances} -setup {
    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 {

test imgPhoto-7.1 {ImgPhotoFree procedure, resource freeing} -setup {
    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 {
test imgPhoto-7.2 {ImgPhotoFree procedures, unlinking} -setup {
    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
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
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







-
+
-
-

















-
-
+
+



-
+
-
-
















-
-
+
+
-
-




-
+








-
+
-
-











-
+
-
-







    destroy .b1
    update
    .c delete all
} -cleanup {
    destroy .c
    image delete photo1
} -result {}
test imgPhoto-7.3 {ImgPhotoFree procedures, multiple visuals} -constraints {
test imgPhoto-7.3 {ImgPhotoFree procedures, multiple visuals} -setup {
    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 {

test imgPhoto-8.1 {ImgPhotoDelete procedure} -body {
    image create photo photo2 -file $teapotPhotoFile
    image delete photo2
} -result {}
test imgPhoto-8.2 {ImgPhotoDelete procedure} -constraints {
test imgPhoto-8.2 {ImgPhotoDelete procedure} -setup {
    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 {

test imgPhoto-9.1 {ImgPhotoCmdDeletedProc procedure} -body {
    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 {
test imgPhoto-10.2 {Tk_ImgPhotoPutBlock, same source and dest img} -setup {
    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 {
test imgPhoto-10.3 {Tk_ImgPhotoPutBlock, same source and dest img} -setup {
    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
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
952
953
954
955
956
957
958


959
960
961
962
963
964
965
966
967

968


969
970
971
972
973
974
975







-
-
+
+







-
+
-
-







} -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 {

test imgPhoto-12.1 {Tk_PhotoPutZoomedBlock} -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 {
test imgPhoto-12.2 {Tk_ImgPhotoPutZoomedBlock, same source and dest img} -setup {
    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
1596
1597
1598
1599
1600
1601
1602











1603
1604
1605
1606
1607
1608
1609
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







+
+
+
+
+
+
+
+
+
+
+







} -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-12.5 {Tk_ImgPhotoPutZoomedBlock, copy from area outside the image, bug [a0241c0e25]} -setup {
    imageCleanup
} -body {
    image create photo photo1 -width 20 -height 20
    image create photo photo2 -width 9 -height 10
    # next line used to loop for a very long time; if the bug is present
    # the CI runner will time out, leading to test suite failure
    photo2 copy photo1 -to 0 5 3 8 -from 21 0
} -cleanup {
    imageCleanup
} -returnCodes error -result {coordinates for -from option extend outside source image}

test imgPhoto-13.1 {check separation of images in different interpreters} -setup {
    imageCleanup
    set data {
	R0lGODlhQgBkAPUAANbWxs7Wxs7OxsbOxsbGxsbGvb3Gvca9vcDAwL21vbW1vbW1tbWtta2t
	ta2ltaWltaWlraWctaWcrZycrZyUrZSUrZSMrZSMpYyMrYyMpYyEpYSEpYR7pYR7nHp7pYRz
	pYRynHtzpXtznHtrnHNrnHNjnGtjnGtjlGtalGNalGNSlGNSjFpSlFpKlFpKjFJKjFJCjFI5
1641
1642
1643
1644
1645
1646
1647
1648

1649
1650
1651
1652
1653
1654
1655
1050
1051
1052
1053
1054
1055
1056

1057
1058
1059
1060
1061
1062
1063
1064







-
+







} -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
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
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







-
+










-
+







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]
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+

-
+









-
+









-
+






-
+








-
+








-
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+















-
+















-
+












-
+


-
+









-
+









-
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    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,
# 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-20.1 {Reject corrupted GIF (binary string)} -setup {
test imgPhoto-18.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 {
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-20.3 {Reject corrupted GIF (file)} -setup {
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-20.4 {Reject truncated GIF (binary string)} -setup {
test imgPhoto-18.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 {
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-20.6 {Reject truncated GIF (file)} -setup {
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.6.1 {Reject truncated GIF in Colormap - ticket 865af0148c - file} -setup {
    set fileName [file join [file dirname [info script]] corruptTruncatedColormap.gif]
} -body {
    image create photo gif1 -file $fileName
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {GIF file truncated}
test imgPhoto-18.6.2 {Reject truncated GIF in Colormap - ticket 865af0148c - data} -setup {
    set fileName [file join [file dirname [info script]] corruptTruncatedColormap.gif]
    set h [open $fileName rb]
    set d [read $h]
    close $h
} -body {
    image create photo gif1 -data $d
} -cleanup {
    catch {image delete gif1}
} -returnCodes error -result {GIF file truncated}
test imgPhoto-20.7 {Reject corrupted GIF (> 4Gb) (binary string)} -constraints {
test imgPhoto-18.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 {
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-20.9 {Reject corrupted GIF (> 4Gb) (file)} -constraints {
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-20.10 {Valid GIF (binary string)} -setup {
test imgPhoto-18.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.
    # Tests 18.11, 18.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 {
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-20.12 {Valid GIF (file)} -setup {
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

set earthPhotoFile [file join [file dirname [info script]] earth.gif]
test imgPhoto-19.1 {Read GIF file with -from option - Bug [1576528]} -body {
    set earthPhotoFile [file join [file dirname [info script]] earth.gif]
    image create photo gif1
    gif1 read $earthPhotoFile -from 152 62 185 97
    list [lindex [lindex [gif1 data] 0] 0] [image width gif1] [image height gif1]
} -cleanup {
    catch {image delete gif1}
} -result {{#d8c8b8} 33 35}
test imgPhoto-19.2 {Read GIF file, copy with -from option} -body {
    set earthPhotoFile [file join [file dirname [info script]] earth.gif]
    image create photo gif1 -file $earthPhotoFile
    image create photo gif2
    gif2 copy gif1 -from 152 62 185 97
    list [lindex [lindex [gif2 data] 0] 0] [image width gif2] [image height gif2]
} -cleanup {
    catch {image delete gif1 ; image delete gif2}
} -result {{#d8c8b8} 33 35}
test imgPhoto-19.3 {Read GIF file with -to option} -body {
    image create photo gif1
    gif1 read $earthPhotoFile -to 100 200
    list [lindex [lindex [gif1 data] 262] 252] [image width gif1] [image height gif1]
} -cleanup {
    catch {image delete gif1}
} -result {{#d8c8b8} 420 400}
test imgPhoto-19.4 {Read GIF file with -from and -to options} -body {
    set earthPhotoFile [file join [file dirname [info script]] earth.gif]
    image create photo gif1
    gif1 read $earthPhotoFile -from 152 62 185 97 -to 100 200
    list [lindex [lindex [gif1 data] 200] 100] [image width gif1] [image height gif1]
} -cleanup {
    catch {image delete gif1}
} -result {{#d8c8b8} 133 235}
test imgPhoto-19.5 {Read GIF file with -from, -to and -shrink options} -body {
    set earthPhotoFile [file join [file dirname [info script]] earth.gif]
    image create photo gif1 -file $teapotPhotoFile
    gif1 read $earthPhotoFile -from 152 62 185 97 -to 80 120 -shrink
    list [lindex [lindex [gif1 data] 120] 80] [image width gif1] [image height gif1]
} -cleanup {
    catch {image delete gif1}
} -result {{#d8c8b8} 113 155}
test imgPhoto-19.6 {Read GIF file with -from option, read large region from small file} -body {
    set earthPhotoFile [file join [file dirname [info script]] earth.gif]
    image create photo gif1
    catch {gif1 read $earthPhotoFile -from 152 62 2000 1000} msg
    list $msg [image width gif1] [image height gif1]
} -cleanup {
    catch {image delete gif1}
} -result {{coordinates for -from option extend outside source image} 0 0}
unset earthPhotoFile

set ousterPhotoFile [file join [file dirname [info script]] ouster.png]
test imgPhoto-20.1 {Read PNG file with -from option - Bug [1576528]} -body {
    image create photo png1
    png1 read $ousterPhotoFile -from 102 62 135 97
    list [lindex [lindex [png1 data] 0] 0] [image width png1] [image height png1]
} -cleanup {
    catch {image delete png1}
} -result {{#c97962} 33 35}
test imgPhoto-20.2 {Read PNG file, copy with -from option} -body {
    image create photo png1 -file $ousterPhotoFile
    image create photo png2
    png2 copy png1 -from 102 62 135 97
    list [lindex [lindex [png2 data] 0] 0] [image width png2] [image height png2]
} -cleanup {
    catch {image delete png1 ; image delete png2}
} -result {{#c97962} 33 35}
test imgPhoto-20.3 {Read PNG file with -to option} -body {
    image create photo png1
    png1 read $ousterPhotoFile -to 100 200
    list [lindex [lindex [png1 data] 262] 202] [image width png1] [image height png1]
} -cleanup {
    catch {image delete png1}
} -result {{#c97962} 242 381}
test imgPhoto-20.4 {Read PNG file with -from and -to options} -body {
    image create photo png1
    png1 read $ousterPhotoFile -from 102 62 135 97 -to 100 200
    list [lindex [lindex [png1 data] 200] 100] [image width png1] [image height png1]
} -cleanup {
    catch {image delete png1}
} -result {{#c97962} 133 235}
test imgPhoto-20.5 {Read PNG file with -from, -to and -shrink options} -body {
    image create photo png1 -file $teapotPhotoFile
    png1 read $ousterPhotoFile -from 102 62 135 97 -to 80 120 -shrink
    list [lindex [lindex [png1 data] 120] 80] [image width png1] [image height png1]
} -cleanup {
    catch {image delete png1}
} -result {{#c97962} 113 155}
test imgPhoto-20.6 {Read PNG file with -from option, read large region from small file} -body {
    image create photo png1
    catch {png1 read $ousterPhotoFile -from 102 62 2000 1000} msg
    list $msg [image width png1] [image height png1]
} -cleanup {
    catch {image delete png1}
} -result {{coordinates for -from option extend outside source image} 0 0}
unset ousterPhotoFile

catch {rename foreachPixel {}}
catch {rename checkImgTrans {}}
catch {rename checkImgTransLoop {}}
imageFinish

# cleanup
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
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1993-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

714
715
716
717
718
719
720
721

722
723
724
725
726
727

728
729
730
731
732
733
734
714
715
716
717
718
719
720

721
722
723
724
725
726

727
728
729
730
731
732
733
734







-
+





-
+







    .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
} -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
} -result 34
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 {
1481
1482
1483
1484
1485
1486
1487
1488
1489


1490
1491
1492
1493
1494
1495
1496
1481
1482
1483
1484
1485
1486
1487


1488
1489
1490
1491
1492
1493
1494
1495
1496







-
-
+
+







    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}]
} -match glob -result [list [list a b c d] foo [list a b c d] \
	{can*t set "::zoo::bar::foo": parent namespace does*t exist}]


# No tests for DisplayListbox:  I don't know how to test this procedure.

test listbox-5.1 {ListboxComputeGeometry procedure} -constraints {
	fonts
} -setup {
2108
2109
2110
2111
2112
2113
2114
2115

2116
2117
2118
2119
2120
2121
2122
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117
2118
2119
2120
2121
2122







-
+







} -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
} -result 20
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
2139
2140
2141
2142
2143
2144
2145
2146

2147
2148
2149
2150
2151
2152
2153
2139
2140
2141
2142
2143
2144
2145

2146
2147
2148
2149
2150
2151
2152
2153







-
+







    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
} -result 1


test listbox-11.1 {ChangeListboxView procedure, boundary conditions for index} -setup {
    destroy .l
} -body {
    listbox .l -height 5
    pack .l
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
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







-
+


-
-
-
+
+
+








-
+









-
+







    destroy .l
} -body {
    listbox .l
    .l insert end a b c d
    .l itemconfigure 0
} -cleanup {
    destroy .l
} -result [list {-background background Background {} {}} \
} -result [list {-background {} {} {} {}} \
	{-bg -background} \
	{-fg -foreground} \
	{-foreground foreground Foreground {} {}} \
	{-selectbackground selectBackground Foreground {} {}} \
	{-selectforeground selectForeground Background {} {}}]
	{-foreground {} {} {} {}} \
	{-selectbackground {} {} {} {}} \
	{-selectforeground {} {} {} {}}]
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 {} {}}
} -result {-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 ...?"}
} -result {wrong # args: should be ".l itemconfigure index ?-option? ?value? ?-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
3148
3149
3150
3151
3152
3153
3154
3155

3156
3157
3158
3159
3160
3161
3162
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
    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
3171
3172
3173
3174
3175
3176
3177

3178
3179
3180
3181
3182
3183
3184
3185







-
+







    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
    event generate .l <1> -x 5 -y 5  ; # <<ListboxSelect>> fires
    selection clear                  ; # <<ListboxSelect>> fires again
    update
    set res
} -cleanup {
    destroy .l
} -result {{.l 0} {{} {}}}

Changes to tests/main.test.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15






-
-
+
+







# 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

23
24
25
26
27
28
29
30


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46


47
48
49
50
51
52
53
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55







-
+
+















-
+
+








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}
	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 "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}
	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
70
71
72
73
74
75
76
77


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104







-
+
+
















-
+








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 €]}
	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
	}
	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:*}
} -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 {
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
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 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.
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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.*)
testConstraint pressbutton [llength [info commands pressbutton]]
set earthPhotoFile [file join [file dirname [info script]] earth.gif]
testConstraint hasEarthPhoto [file exists $earthPhotoFile]
testConstraint movemouse [llength [info commands movemouse]]

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"}
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
170
171
172
173
174
175
176








177
178
179
180
181
182
183







-
-
-
-
-
-
-
-







    .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"}
292
293
294
295
296
297
298
299
300


301
302
303
304
305
306
307
308
283
284
285
286
287
288
289


290
291

292
293
294
295
296
297
298







-
-
+
+
-







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
set earthPhotoFile [file join [file dirname [info script]] earth.gif]
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
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
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







-
+
-
-



-
+
-
-








-
+
-
-








-
+
-
-



-
+
-
-








-
+
-
-







    .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 {
test menu-2.121 {entry configuration options 0 -image image1 tearoff} -body {
    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 {
test menu-2.122 {entry configuration options 1 -image image1 command} -setup {
    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 {
test menu-2.123 {entry configuration options 2 -image image1 cascade} -setup {
    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 {
test menu-2.124 {entry configuration options 3 -image image1 separator} -body {
    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 {
test menu-2.125 {entry configuration options 4 -image image1 checkbutton} -setup {
    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 {
test menu-2.126 {entry configuration options 5 -image image1 radiobutton} -setup {
    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}
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
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







-
+
-
-



-
+
-
-



-
+
-
-



-
+
-
-



-
+
-
-








-
+
-
-







    .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 {
test menu-2.181 {entry configuration options 0 -selectimage image1 tearoff} -body {
    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 {
test menu-2.182 {entry configuration options 1 -selectimage image1 command} -body {
    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 {
test menu-2.183 {entry configuration options 2 -selectimage image1 cascade} -body {
    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 {
test menu-2.184 {entry configuration options 3 -selectimage image1 separator} -body {
    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 {
test menu-2.185 {entry configuration options 4 -selectimage image1 checkbutton} -setup {
    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 {
test menu-2.186 {entry configuration options 5 -selectimage image1 radiobutton} -setup {
    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}
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
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







-
-
+
-
-








-
+


-
+










-
+





-
+


-
+





-
+






-
+


-
+






-
+


-
+





-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+





-
+





-
+





-
+


-
+





-
+





-
+




-
+


-
+




-
+


-
+




-
-
+
+

-
+





-
+




-
+


-
+





-
+


-
+





-
+





-
+





-
+




-
+


-
+





-
+


-
+







-
+


-
+








-
+


-
+








-
+













-
+





-
+





-
+





-
+





-
+


-
+





-
+





-
+





-
+


-
+





-
+


-
+






-
+


-
+





-
+





-
+










-
+


-
+





-
+





-
+


-
+




-
+


-
+




-
+


-
+






-
+


-
+





-
+


-
+




-
+


-
+




-
+


-
+

-
+





-
+


-
+




-
+


-
+




-
+


-
+

-
+








-
+


-
+







-
+


-
+




-
+


-
+




-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+




-
+


-
+




-
+


-
+

-
+






-
+


-
+




-
+


-
+




-
+




-
+






-
+




-
+






-
+


-
+




-
+







} -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
image delete image1
}



test menu-3.1 {MenuWidgetCmd procedure} -setup {
    destroy .m1
} -body {
    menu .m1
    .m1
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 option ?arg ...?"}
test menu-3.2 {MenuWidgetCmd, Tcl_Preserve and Tcl_Release} -constraints {
	nonUnixUserInteraction
    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
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 activate index"}
test menu-3.4 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
    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
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 add separator
    .m1 activate 2
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.6 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -state disabled
    .m1 activate 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.7 {MenuWidgetCmd procedure, "activate" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 activate 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.8 {MenuWidgetCmd procedure, "add" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add
} -cleanup {
	destroy .m1
    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
    destroy .m1
} -body {
    menu .m1
    .m1 add foo
} -cleanup {
	destroy .m1
    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
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.11 {MenuWidgetCmd procedure, "cget" option} -setup {
	destroy .m1
    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
    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
    destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Some string"
    .m1 cget -postcommand
} -cleanup {
	destroy .m1
    destroy .m1
} -result {Some string}
test menu-3.14 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
    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
    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
    destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.17 {MenuWidgetCmd procedure, "clone" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 clone .m1.clone1 tearoff
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.18 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    llength [.m1 configure]
} -cleanup {
	destroy .m1
} -result 21
    destroy .m1
} -result 20
test menu-3.19 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
    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
    destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "A random String"
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.21 {MenuWidgetCmd procedure, "configure" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 configure -postcommand "Another string"
    lindex [.m1 configure -postcommand] 4
} -cleanup {
	destroy .m1
    destroy .m1
} -result {Another string}
test menu-3.22 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
    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
    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
    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
    destroy .m1
} -body {
    menu .m1
    .m1 delete 0
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.26 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "foo"
    .m1 delete 1 0
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.27 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
    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
    destroy .m1
} -result {}
test menu-3.28 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
    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
    destroy .m1
} -result {}
test menu-3.29 {MenuWidgetCmd procedure, "delete" option} -setup {
	destroy .m1
    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
    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
    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
    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
    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
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
	destroy .m1
    destroy .m1
} -result {test}
test menu-3.34 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
    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
    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
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    llength [.m1 entryconfigure 1]
} -cleanup {
	destroy .m1
    destroy .m1
} -result 15
test menu-3.37 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
	destroy .m1
    destroy .m1
} -result {test}
test menu-3.38 {MenuWidgetCmd procedure, "entryconfigure" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 entryconfigure 1 -label "changed"
    lindex [.m1 entryconfigure 1 -label] 4
} -cleanup {
	destroy .m1
    destroy .m1
} -result {changed}
test menu-3.39 {MenuWidgetCmd procedure, "index" option} -setup {
	destroy .m1
    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
    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
    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
    destroy .m1
} -result {1 3 5 6}
test menu-3.42 {MenuWidgetCmd procedure, "insert" option} -setup {
	destroy .m1
    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
    destroy .m1
} -body {
    menu .m1
    .m1 insert 1 command -label "test"
    .m1 entrycget 1 -label
} -cleanup {
	destroy .m1
    destroy .m1
} -result {test}
test menu-3.44 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 invoke
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 invoke index"}
test menu-3.45 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 invoke foo
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.46 {MenuWidgetCmd procedure, "invoke" option} -setup {
	destroy .m1
    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
    destroy .m1
} -returnCodes ok -result {hello hello {}}
test menu-3.47 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
    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
    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
    destroy .m1
} -body {
    menu .m1
    .m1 post foo 40
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {expected integer but got "foo"}
test menu-3.49 {MenuWidgetCmd procedure, "post" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 post 40 bar
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {expected integer but got "bar"}
test menu-3.50 {MenuWidgetCmd procedure, "post" option} -constraints {
	nonUnixUserInteraction
    nonUnixUserInteraction
} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.50: hit Escape" -command "puts hello"
    .m1 post 40 40
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.51 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 postcascade
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 postcascade index"}
test menu-3.52 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 postcascade foo
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.53 {MenuWidgetCmd procedure, "postcascade" option} -constraints {
	nonUnixUserInteraction
    nonUnixUserInteraction
} -setup {
	destroy .m1 .m2
    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
    destroy .m1 .m2
} -result {}
test menu-3.54 {MenuWidgetCmd procedure, "postcascade" option} -setup {
	destroy .m1 .m2
    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
    destroy .m1 .m2
} -result {}
test menu-3.55 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 type
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 type index"}
test menu-3.56 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 type foo
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {bad menu entry index "foo"}
test menu-3.57 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {command}
test menu-3.58 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add separator
    .m1 type 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {separator}
test menu-3.59 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add checkbutton -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {checkbutton}
test menu-3.60 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add radiobutton -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {radiobutton}
test menu-3.61 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add cascade -label "test"
    .m1 type 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result {cascade}
test menu-3.62 {MenuWidgetCmd procedure, "type" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1 -tearoff 1
    .m1 type 0
} -cleanup {
	destroy .m1
    destroy .m1
} -result {tearoff}
test menu-3.63 {MenuWidgetCmd procedure, "unpost" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 unpost foo
} -cleanup {
	destroy .m1
    destroy .m1
} -returnCodes error -result {wrong # args: should be ".m1 unpost"}
test menu-3.64 {MenuWidgetCmd procedure, "unpost" option} -constraints {
	nonUnixUserInteraction
    nonUnixUserInteraction
} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 add command -label "menu-3.64 - hit Escape"
    .m1 post 40 40
    .m1 unpost
} -cleanup {
	destroy .m1
    destroy .m1
} -result {}
test menu-3.65 {MenuWidgetCmd procedure, "yposition" option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 yposition
} -cleanup {
	destroy .m1
    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
    destroy .m1
} -body {
    menu .m1 -tearoff 0
    .m1 yposition 1
} -cleanup {
	destroy .m1
    destroy .m1
} -result 0
test menu-3.66b {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    notAqua
} -setup {
	destroy .m1
    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
    destroy .m1
} -result 1
test menu-3.66c {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
    aqua
} -setup {
	destroy .m1
    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
    destroy .m1
} -result 0
test menu-3.67 {MenuWidgetCmd procedure, bad option} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    .m1 foo
} -cleanup {
	destroy .m1
    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
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
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







-
-
-
-
-
-
-
-








-
+








-
+










-
+







    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
    -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}
    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
            [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}
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
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







-
+











-
+











-
+











-
+











-
+









-
+








-
+








-
+







    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
    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
    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
    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
    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
    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
    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
    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
    destroy .m1
} -result {0 {} 1 {bad menu entry index "test"}}

test menu-5.1 {DestroyMenuInstance} -setup {
    destroy .m1
} -body {
    menu .m1
    destroy .m1
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
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







-
+







-
+








-
+








-
+








-
+


-
+







} -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]
    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]
    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]
    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]
    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]
    list [destroy .m4] [destroy .m1]
} -returnCodes ok -result {{} {}}
test menu-6.14 {TkDestroyMenu} -setup {
	destroy .m1
    destroy .m1
} -body {
    menu .m1
    . configure -menu .m1
    list [destroy .m1] [. configure -menu ""]
} -returnCodes ok -result {{} {}}
test menu-6.15 {TkDestroyMenu} -setup {
    deleteWindows
2241
2242
2243
2244
2245
2246
2247








2248
2249
2250
2251
2252
2253
2254
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217







+
+
+
+
+
+
+
+







    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-6.17 {TkDestroyMenu - bug 14a9b62e1d} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -command {destroy .m1}
    .m1 invoke end
    winfo exists .m1
} -result {0}

test menu-7.1 {UnhookCascadeEntry} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 add command -label "test"
    destroy .m1
2333
2334
2335
2336
2337
2338
2339
2340

2341
2342
2343
2344
2345
2346
2347
2296
2297
2298
2299
2300
2301
2302

2303
2304
2305
2306
2307
2308
2309
2310







-
+







    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 {
test menu-8.2 {DestroyMenuEntry} -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]
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
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







-
+














-
+














-
+














+
+







    image create test image1
    .m1 entryconfigure 1 -image image1
} -cleanup {
    deleteWindows
    imageCleanup
} -result {}
test menu-11.19 {ConfigureMenuEntry} -constraints {
    testImageType hasEarthPhoto
    testImageType
} -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
    testImageType
} -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
    testImageType
} -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 {}

unset earthPhotoFile


test menu-12.1 {ConfigureMenuCloneEntries} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 clone .m2
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
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







-
-
-
+
+
+












-
+










-
+










-
+









-
+









-
+







    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 ""]
            -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]
            [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 ""]
            [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]
            [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]
            [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]
            [set foo "goodbye"] [unset foo]
} -cleanup {
    deleteWindows
} -result {{} goodbye {}}
test menu-17.6 {MenuVarProc [5d991b822e]} -setup {
    deleteWindows
} -body {
    # Want this not to crash
3353
3354
3355
3356
3357
3358
3359




















































3360
3361
3362
3363
3364
3365
3366
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







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-20.12 {CloneMenu - copied bindings on empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 0
    bind .m1 <<Test>> {append x <<Test>>}
    .m1 clone .m2 tearoff
    .m2 post 100 100
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.13 {CloneMenu - copied bindings on non-empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 1
    bind .m1 <<Test>> {append x <<Test>>}
    .m1 clone .m2 tearoff
    .m2 post 100 100
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.14 {CloneMenu - new binding on empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 0
    .m1 clone .m2 tearoff
    .m2 post 100 100
    bind .m1 <<Test>> {append x <<Test>>}
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.15 {CloneMenu - new binding on non-empty menu} -setup {
    deleteWindows
    set x {}
} -body {
    menu .m1 -tearoff 1
    .m1 clone .m2 tearoff
    .m2 post 100 100
    bind .m1 <<Test>> {append x <<Test>>}
    event generate .m2 <<Test>>
    return $x
} -result {<<Test>>}
test menu-20.16 {CloneMenu - bindtags} -setup {
    deleteWindows
} -body {
    menu .m1
    bindtags .m1 [linsert [bindtags .m1] 1 .m1.sub1]
    .m1 clone .m2
    bindtags .m2
} -result {.m2 .m1 .m1.sub1 Menu all}

test menu-21.1 {MenuDoYPosition} -setup {
    deleteWindows
} -body {
    menu .m1
    .m1 yposition glorp
} -returnCodes error -result {bad menu entry index "glorp"}
3431
3432
3433
3434
3435
3436
3437


































































3438
3439
3440
3441
3442
3443
3444
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    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-22.6 {GetIndexFromCoords: syntax error in @x,y indices} -setup {
    deleteWindows
} -body {
    menu .m
    .m add command -label "First entry"
    .m add command -label "Second entry"
    .m add command -label "Last entry"
    .m index @4bogus
} -cleanup {
    deleteWindows
}  -returnCodes error -result {bad menu entry index "@4bogus"}
test menu-22.7 {GetIndexFromCoords: syntax error in @x,y indices} -setup {
    deleteWindows
} -body {
    menu .m
    .m add command -label "First entry"
    .m add command -label "Second entry"
    .m add command -label "Last entry"
    .m index @10,4bogus
} -cleanup {
    deleteWindows
}  -returnCodes error -result {bad menu entry index "@10,4bogus"}
test menu-22.8 {GetIndexFromCoords: syntax error in @x,y indices} -setup {
    deleteWindows
} -body {
    menu .m
    .m add command -label "First entry"
    .m add command -label "Second entry"
    .m add command -label "Last entry"
    .m index @10,bogus
} -cleanup {
    deleteWindows
}  -returnCodes error -result {bad menu entry index "@10,bogus"}
test menu-22.9 {GetIndexFromCoords: index type pecedence} -setup {
    deleteWindows
} -body {
    menu .m -tearoff 0
    .m add command -label "First entry"
    .m add command -label "@42nd street"
    .m add command -label "Last entry"
    .m index "@42nd*"  ; # shall be interpreted as a pattern, not as @42
} -cleanup {
    deleteWindows
} -result {1}

test menu-22.10 {tk_popup on separator entry} -setup {
    deleteWindows
} -constraints {x11} -body {
    menu .m1
    label .l -text ClickMe!
    .m1 add command -label "Example 1" -command bell
    .m1 add command -label "Example 2" -command bell
    .m1 add separator
    .m1 add command -label "Example Other" -command "bell;bell"
    tk_popup .m1 100 100 2
    set waiting 0
    tkwait visibility .m1
    after 333 incr waiting
    vwait waiting
    .m1 invoke 4
    after 333 incr waiting
    vwait waiting
    destroy .m1
} -cleanup {
    deleteWindows
} -result {}

test menu-23.1 {RecursivelyDeleteMenu} -setup {
    deleteWindows
} -body {
    menu .m1
    . configure -menu .m1
    . configure -menu ""
3477
3478
3479
3480
3481
3482
3483
3484

3485
3486
3487
3488
3489
3490
3491
3560
3561
3562
3563
3564
3565
3566

3567
3568
3569
3570
3571
3572
3573
3574







-
+







} -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]
            [destroy .m] [destroy hideme]
} -result {0 {} {} {} {}}


test menu-25.1 {TkSetWindowMenuBar} -setup {
    deleteWindows
} -body {
    . configure -menu ""
3834
3835
3836
3837
3838
3839
3840
3841

3842
3843
3844
3845
3846
3847
3848
3917
3918
3919
3920
3921
3922
3923

3924
3925
3926
3927
3928
3929
3930
3931







-
+







    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"
            -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 {
3857
3858
3859
3860
3861
3862
3863
3864
3865


3866
3867
3868
3869
3870
3871
3872
3940
3941
3942
3943
3944
3945
3946


3947
3948
3949
3950
3951
3952
3953
3954
3955







-
-
+
+







} -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
        .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 {
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
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







-
+




-
+








-
+







    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]
    set l [interp hidden]
    menu .m
    interp hide {} .m
    destroy .m
    set result [list [winfo children .] [interp hidden]]
	expr {$result eq [list {} $l]}
    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
    altDisplay
} -setup {
    deleteWindows
} -body {
    toplevel .one
    menu .one.m
    toplevel .two -screen $::env(TK_ALT_DISPLAY)
    menu .two.m
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
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







-
+










-
-
+















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










    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 {
} -constraints {x11} -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
    controlPointerWarpTiming
    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

test menu-39.1 {empty -type - bug be8f5b9fc2} -setup {
    catch {destroy .m}
} -body {
    menu .m -type {}
} -cleanup {
    destroy .m
} -returnCodes error -result {ambiguous type "": must be normal, tearoff, or menubar}

test menu-39.2 {use-after-free fix - bug 1797555fff} -setup {
    toplevel .t
    menu .t.menubar -type menubar
    menu .t.menubar.select -title Select
    menu .t.menubar.select.chain -title Chain
    .t.menubar.select insert 1 cascade -menu .t.menubar.select.chain -label Chain
    .t.menubar add cascade -menu .t.menubar.select -label Select
    .t configure -menu .t.menubar
    .t.menubar.select.chain insert 1 command
    update idletasks
} -body {
    # The following two lines caused Tk to read from and write to freed memory
    destroy .t.menubar.select.chain
    .t.menubar.select delete 1
} -cleanup {
    destroy .t
} -result {}

test menu-40.1 {Use-after-free if menu destroyed while posted - bug 09a11fb1228f} -setup {
} -constraints {pressbutton} -body {
    set done false
    event generate {} <Motion> -x 100 -y 100
    toplevel .t
    menu .t.m
    .t.m add command -command {puts Marco} -label Marco
    .t.m add command -command {puts Polo} -label Polo
    after 1000 {.t.m post 500 500}
    after 2000 {destroy .t}
    after 2500 {pressbutton 530 510}
    after 3000 {set done true}
    tkwait variable done
}

test menu-40.2 {Use-after-free if menu destroyed while posted - bug 09a11fb1228f} -setup {
} -constraints {movemouse} -body {
    set done false
    event generate {} <Motion> -x 100 -y 100
    toplevel .t
    menu .t.m
    .t.m add command -command {puts Marco} -label Marco
    .t.m add command -command {puts Polo} -label Polo
    after 1000 {.t.m post 500 500}
    after 2000 {movemouse 530 510}
    after 3000 {destroy .t}
    after 3500 {movemouse 530 530}
    after 4000 pressbutton 530 530
    after 4500 {set done true}
    tkwait variable done
    pressbutton 530 510
}

# cleanup
imageFinish
deleteWindows
cleanupTests
return

# Local variables:
# mode: tcl
# End:
Changes to tests/menuDraw.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit
Changes to tests/menubut.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
538
539
540
541
542
543
544
545

546
547
548
549
550
551
552
538
539
540
541
542
543
544

545
546
547
548
549
550
551
552







-
+







    menubutton .mb1
    rename .mb1 {}
    list [info command .mb*] [winfo children .]
} -cleanup {
    deleteWindows
} -result {{} {}}

if {[tk windowingsystem] == "aqua"} {
if {[tk windowingsystem] eq "aqua"} {
    set extraWidth 36
} else {
    set extraWidth 0
}
test menubutton-7.1 {ComputeMenuButtonGeometry procedure} -constraints {
    testImageType
} -setup {
Changes to tests/message.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::loadTestedCommands
eval tcltest::configure $argv

26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360







-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+



















-
+







    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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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"}
} -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"}
} -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"}
} -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"}
} -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}
} -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"}
} -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"}
} -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}
} -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"
388
389
390
391
392
393
394
395

396
397
398
399
400

401
402
403
404

405
406
407

408
409
410
411
412

413
414
415

416
417
418
419
420
421
422
388
389
390
391
392
393
394

395
396
397
398
399

400
401
402
403

404
405
406

407
408
409
410
411

412
413
414

415
416
417
418
419
420
421
422







-
+




-
+



-
+


-
+




-
+


-
+







    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"}
} -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 ...?"}
} -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"}
} -returnCodes error -result {bad window path name "foo"}
test message-2.3 {Tk_MessageObjCmd procedure} -body {
    catch {message foo}
    winfo child .
    winfo children .
} -result {}

test message-2.4 {Tk_MessageObjCmd procedure} -body {
    message .s -gorp dump
} -returnCodes {error} -result {unknown option "-gorp"}
} -returnCodes error -result {unknown option "-gorp"}
test message-2.5 {Tk_MessageObjCmd procedure} -body {
    catch {message .s -gorp dump}
    winfo child .
    winfo children .
} -result {}


test message-3.1 {MessageWidgetObjCmd procedure} -setup {
    message .m
} -body {
    .m
Changes to tests/msgbox.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

117
118
119
120
121
122
123
90
91
92
93
94
95
96

97
98
99
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 {!$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 <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 <Key> -keysym Return
	event generate $w <KeyPress> -keysym Return
    }
}
#
# Try out all combinations of (type) x (default button) and
# (type) x (icon).
#
test msgbox-2.1 {tk_messageBox command} -constraints {
Changes to tests/obj.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/oldpack.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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.
# Copyright (c) 1991-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
25
26
27
28
29
30
31
32





33

34
35
36
37
38
39
40
41








-
-
-
-
-

-
+







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
    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
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
438

439
440
441
442
443
444
445
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412
413
414

415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440







-
+









-
+









-
+







-
+







    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] {
    foreach i [winfo children .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] {
    foreach i [winfo children .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] {
    foreach i [winfo children .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] {
    foreach i [winfo children .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}

453
454
455
456
457
458
459
460

461
462
463

464
465
466
467
468
469
470
448
449
450
451
452
453
454

455
456
457

458
459
460
461
462
463
464
465







-
+


-
+







    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}
} -returnCodes error -result {bad option "gorp": must be configure, content, forget, info, propagate, or slaves}
test oldpack-8.4 {syntax errors} -body {
    pack a .pack
} -returnCodes error -result {bad option "a": must be configure, content, forget, info, or propagate}
} -returnCodes error -result {bad option "a": must be configure, content, forget, info, propagate, or slaves}
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
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
488
489
490
491
492
493
494

495
496
497
498
499
500
501
502







-
+







    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 "."}
} -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 {
545
546
547
548
549
550
551
552
553
554
555
556
557
558
540
541
542
543
544
545
546

547
548
549
550
551
552







-






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

Changes to tests/option.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

357
358
359
360
361
362
363
364
365


366
367
368
369
370
371
372
357
358
359
360
361
362
363


364
365
366
367
368
369
370
371
372







-
-
+
+







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}
    list [catch {option read non-existent} msg] [string tolower $msg]
} -result {1 {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
397
398
399
400
401
402
403
404

405
406
407

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425


426
427
428
429
430
431


432

433
434
435
436
437
438
439
440
441
397
398
399
400
401
402
403

404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423


424
425
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442
443







-
+


-
+
















-
-
+
+






+
+
-
+









} -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-15.11 {database files} {option get . {x 4} color} br\xf3wn

test option-16.1 {ReadOptionFile} -body {
    set option4 [makeFile {} option.file3]
    set option4 [makeFile {} option.file4]
    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]
test option-16.2 {ticket 766ef52f3} -body {
    set option5 [makeFile {} option.file5]
    set file [open $option5 w]
    fconfigure $file -translation crlf
    puts $file "*notok: $opt162list"
    close $file
    option read $option5 userDefault
    option get . notok notok
} -cleanup {
    removeFile $option5
} $opt162list
} -result $opt162list

deleteWindows

# cleanup
cleanupTests
return



Added tests/ouster.png.

cannot compute difference between binary files

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


1
2
3



4
5
6
7
8
9
10
11
12
13

14
15
16
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 out the "pack" command of Tk.  It is
# organized in the standard fashion for Tcl tests.
# 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.
# Copyright (c) 1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
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]
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
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







-
+








-
+











-
+
+







    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}
} -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}
} -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}
} -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]
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
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







-
+





-
+




-
+







} -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 "."}
} -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"}
} -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}
} -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}
1358
1359
1360
1361
1362
1363
1364
1365

1366
1367
1368
1369
1370
1371
1372
1359
1360
1361
1362
1363
1364
1365

1366
1367
1368
1369
1370
1371
1372
1373







-
+







} -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}
} -returnCodes error -result {bad option "lousy": must be configure, content, forget, info, propagate, or slaves}

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
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
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







-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-

-
+
-
-
-
-
-


-
+




-
+
-
-

-
+
+

-
+


-
+
-



-

+




-
+




-
-
-
+
+
+

-
+




-
+

















-
+

















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







    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
# Tests pack-18.1.1 and pack-18.2 are constrained with failsOnUbuntu
# because they are failing in the GitHub CI environment, using Linux Ubuntu.
# These tests are also constrained with failsOnXQuarz because they fail
    }
} else {
    proc packUpdate {} {
    }
# on macOS when building with clang --disable-aqua (which uses XQuartz)
# (this is the case both at GitHub CI and on a real Mac).
# Analysis shows that, on both cases, WaitForMapNotify is giving up on
# waiting for the MapNotify event that should show up when running
# 'wm iconify'. The timeout delay (2s) is exceeded without the unmapping
# having happened. The cause for this is unknown (see comments in WaitForMapNotify).

}

test pack-18.1 {unmap content when container unmapped} -constraints {
    tempNotPc failsOnUbuntu failsOnXQuarz
# Tests pack-18.1.* are constrained because on Windows, when the width/height
# is configured while the window is unmapped, the changes don't take
# effect until the window is remapped. This is apparently by design of the
# OS, and Tk accommodates this behavior (see UpdateGeometryInfo() and
# ConfigureTopLevel() in tkWinWm.c).
# pack-18.1.1 checks that, on Linux or macOS, width/height changes are taken
# into account while the window is unmapped.
# pack-18.1.2 checks that, on Windows, width/height changes are taken into
# account on window remapping.
test pack-18.1.1 {unmap content when container unmapped} -constraints {
    macOrUnix failsOnUbuntu failsOnXQuarz
} -setup {
    eval destroy [winfo child .pack]
    destroy {*}[winfo children .pack]
    # 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
} -body {
    frame .pack.a -width 100 -height 50 -relief raised -bd 2
    pack .pack.a
    update
    set result [winfo ismapped .pack.a]
    wm iconify .pack
    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]
} -result {1 0 200 75 0 1}
test pack-18.1.2 {unmap content when container unmapped} -constraints {
    win
} -setup {
    destroy {*}[winfo children .pack]
    # 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

} -body {
    # 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
    update
    set result [winfo ismapped .pack.a]
    wm iconify .pack
    lappend result [winfo ismapped .pack.a]
    .pack.a configure -width 200 -height 75
    update idletasks
    update
    lappend result [winfo width .pack.a ] [winfo height .pack.a] \
    [winfo ismapped .pack.a]
    wm deiconify .pack
    packUpdate
    update
    lappend result [winfo width .pack.a] [winfo height .pack.a]
    lappend result [winfo ismapped .pack.a]
} -result {1 0 200 75 0 1}
} -result {1 0 200 75 1}

test pack-18.2 {unmap content when container unmapped} -constraints {failsOnUbuntu failsOnXQuarz} -setup {
    eval destroy [winfo child .pack]
    destroy {*}[winfo children .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
} -body {
    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
    update
    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]
    update
    lappend result [winfo width .pack.b] [winfo height .pack.b] \
            [winfo ismapped .pack.b]
    wm deiconify .pack
    packUpdate
    update
    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]}
    catch {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]}
    catch {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:
Changes to 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
1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 interaction between Tk's "pack" and
# "grid" commands.
# It is organized in the standard fashion for Tcl tests.
#
# Copyright © 2008 Peter Spjuth
# Copyright (c) 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}
} -result {cannot use geometry manager pack inside . which already has slaves managed by grid}

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}
} -result {cannot use geometry manager grid inside . which already has slaves managed by pack}

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 {
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196







-
+















-
+
















-
+















-
+







    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}
} -result {cannot use geometry manager grid inside . which already has slaves managed by pack}

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}
} -result {cannot use geometry manager pack inside . which already has slaves managed by grid}

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}
} -result {cannot use geometry manager pack inside . which already has slaves managed by grid}

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}
} -result {cannot use geometry manager grid inside . which already has slaves managed by pack}

test packgrid-3.1 {stealing content} -setup {
    grid propagate . true
    pack propagate . true
    label .p -text PACK
    label .g -text GRID
} -body {
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254







-
+














-
+







    # 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}
} -result {cannot use geometry manager pack inside . which already has slaves managed by grid}

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}
} -result {cannot use geometry manager grid inside . which already has slaves managed by pack}

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
Changes to tests/panedwindow.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

289
290
291
292
293
294
295
296

297
298
299
300
301

302
303
304
305
306

307
308
309
310
311
312
313
314
315

316
317
318
319
320

321
322
323
324
325

326
327
328

329
330
331
332
333
334
335
336
337

338
339
340

341
342
343
344
345
346
347
348
349
350
351

352
353
354

355
356
357
358
359
360
361
362
363
364
365

366
367
368

369
370
371
372
373
374
375
376
377
378
379
380

381
382
383

384
385
386
387
388
389
390
391

392
393
394
395
396

397
398
399
400
401

402
403
404

405
406
407
408
409

410
411
412
413
414

415
416
417
418
419

420
421
422

423
424
425
426
427

428
429
430

431
432
433
434
435

436
437
438

439
440
441
442
443


444
445
446

447
448
449

450
451
452
453
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
289
290
291
292
293
294
295

296
297
298
299
300

301
302
303
304
305

306
307
308
309
310
311
312
313
314

315
316
317
318
319

320
321
322
323
324

325
326
327

328
329
330
331
332
333
334
335
336

337
338
339

340
341
342
343
344
345
346
347
348
349
350

351
352
353

354
355
356
357
358
359
360
361
362
363
364

365
366
367

368
369
370
371
372
373
374
375
376
377
378
379

380
381
382

383
384
385
386
387
388
389
390

391
392
393
394
395

396
397
398
399
400

401
402
403

404
405
406
407
408

409
410
411
412
413

414
415
416
417
418

419
420
421

422
423
424
425
426

427
428
429

430
431
432
433
434

435
436
437

438
439
440
441


442
443
444
445

446
447
448

449
450
451
452


453
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







-
+




-
+




-
+








-
+




-
+




-
+


-
+








-
+


-
+










-
+


-
+










-
+


-
+











-
+


-
+







-
+




-
+




-
+


-
+




-
+




-
+




-
+


-
+




-
+


-
+




-
+


-
+



-
-
+
+


-
+


-
+



-
-
+
+


-
+


-
+




-
-
+
+


-
+


-
+




-
-
+
+


-
+


-
+






-
+


-
+





-
-
+
+

-
+


-
+





-
-
-
+
+
+

-
+




-
+




-
+


-
+




-
+


-
+




-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+






-
+




-
+




-
+


-
+




-
+


-
+




-
+


-
+





-
+


-
+





-
+




-
+







-
+


-
+








-
+


-
+







-
+




-
+




-
+


-
+




-
+


-
+




-
+


-
+





-
+


-
+





-
+


-
+






-
+


-
+






-
+


-
+






-
+


-
+





-
+




-
+









-
+










-
+


-
+







-
+











-
+












-
+


-
+









-
+


-
+








-
+


-
+









-
+










-
+







-
+


-
+



-
+



-
+


-
+



-
+



-
+


-
+



-
+






-
+


-
+



-
+






-
+


-
+



-
+







-
+




-
+









-
+


-
+










-
+


-
+



-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+










-
+


-
+










-
+


-
+







-
+


-
+








-
+


-
+










-
+


-
+










-
+


-
+










-
+


-
+








-
+


-
+









-
+


-
+











-
+




-
+














-
+







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
    deleteWindows
} -body {
    panedwindow .p
    .p foo
} -cleanup {
	deleteWindows
    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
    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
    deleteWindows
} -result [list [list .b .c] [list .c]]


test panedwindow-4.1 {forget subcommand} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p forget
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p forget widget ?widget ...?"}
test panedwindow-4.2 {forget subcommand, forget one from start} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list {.b .c} .c]
test panedwindow-4.3 {forget subcommand, forget one from end} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list {.b .c .d} {.b .c}]
test panedwindow-4.4 {forget subcommand, forget multiple} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list {.b .c .d} .d]
test panedwindow-4.5 {forget subcommand, panes are unmapped} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 1 1 0 1]
test panedwindow-4.6 {forget subcommand, changes reqsize of panedwindow} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 44 20]


test panedwindow-5.1 {sash subcommand} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash option ?arg ...?"}
test panedwindow-5.2 {sash subcommand} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash foo
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {bad option "foo": must be coord, dragto, mark, or place}


test panedwindow-6.1 {sash coord subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash coord
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash coord index"}
test panedwindow-6.2 {sash coord subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 0 -sashwidth 4
    .p sash coord 0
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-6.3 {sash coord subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash coord foo
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-6.4 {sash coord subcommand sashes correctly placed} -setup {
	deleteWindows
    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]
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result [list 22 0]
test panedwindow-6.5 {sash coord subcommand sashes correctly placed} -setup {
	deleteWindows
    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]
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
	deleteWindows
    deleteWindows
} -result [list 50 0]
test panedwindow-6.6 {sash coord subcommand, sashes correctly placed} -setup {
	deleteWindows
    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]
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result [list 0 22]
test panedwindow-6.7 {sash coord subcommand, sashes correctly placed} -setup {
	deleteWindows
    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]
            [frame .p.f2 -width 20 -height 20] \
            [frame .p.f3 -width 20 -height 20]
    .p sash coord 1
} -cleanup {
	deleteWindows
    deleteWindows
} -result [list 0 50]
test panedwindow-6.8 {sash coord subcommand, errors} -setup {
	deleteWindows
    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
    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
    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
            [catch {.p sash coord  0} msg] $msg \
            [catch {.p sash coord  1} msg] $msg
} -cleanup {
	deleteWindows
    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
    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
            [catch {.p sash coord  0} msg] \
            [catch {.p sash coord  1} msg] $msg \
            [catch {.p sash coord  2} msg] $msg
} -cleanup {
	deleteWindows
    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
    deleteWindows
} -body {
    panedwindow .p
    .p sash mark
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash mark index ?x y?"}
test panedwindow-7.2 {sash mark subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash mark foo
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.3 {sash mark subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash mark 0 foo bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-7.4 {sash mark subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 foo bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-7.5 {sash mark subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 0 bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-7.6 {sash mark subcommand, mark defaults to 0 0} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result [list 0 0]
test panedwindow-7.7 {sash mark subcommand, set mark} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash mark 0 10 10
    .p sash mark 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result [list 10 10]


test panedwindow-8.1 {sash dragto subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash dragto
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash dragto index x y"}
test panedwindow-8.2 {sash dragto subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash dragto foo bar baz
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.3 {sash dragto subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash dragto 0 foo bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-8.4 {sash dragto subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 foo bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-8.5 {sash dragto subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash dragto 0 0 bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}


test panedwindow-9.1 {sash mark/sash dragto interaction} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 30 0]
test panedwindow-9.2 {sash mark/sash dragto interaction} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 0 30]
test panedwindow-9.3 {sash mark/sash dragto, respects minsize} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 15 0]


test panedwindow-10.1 {sash place subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash place
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p sash place index x y"}
test panedwindow-10.2 {sash place subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash place foo bar baz
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.3 {sash place subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p sash place 0 foo bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {invalid sash index}
test panedwindow-10.4 {sash place subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 foo bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-10.5 {sash place subcommand, errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p sash place 0 0 bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-10.6 {sash place subcommand, moves sash} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 10 0]
test panedwindow-10.7 {sash place subcommand, moves sash} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 0 10]
test panedwindow-10.8 {sash place subcommand, respects minsize} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 15 0]
test panedwindow-10.9 {sash place subcommand, respects minsize} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg pink]
    .p sash place 0 2 0
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {invalid sash index}


test panedwindow-11.1 {moving sash changes size of pane to left} -setup {
	deleteWindows
    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
    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
    deleteWindows
} -result {20 10}
test panedwindow-11.3 {moving sash does not change reqsize of panedwindow} -setup {
	deleteWindows
    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
    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
    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
    deleteWindows
} -result {10 5}
test panedwindow-11.6 {moving sash does not change reqsize of panedwindow} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 24 24]
test panedwindow-11.7 {moving sash does not alter reqsize of widget} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 10 10]
test panedwindow-11.8 {moving sash restricted to minsize} -setup {
	deleteWindows
    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
    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
    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
    deleteWindows
} -result [list {20 0} {40 0}]
test panedwindow-11.11 {moving sash right pushes other sashes} -setup {
	deleteWindows
    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]
            [frame .f3 -width 20 -height 30]
    .p sash place 0 80 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
    deleteWindows
} -result {{60 0} {64 0}}
test panedwindow-11.12 {moving sash left pushes other sashes} -setup {
	deleteWindows
    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]
            [frame .f3 -width 20 -height 30]
    .p sash place 1 0 0
    list [.p sash coord 0] [.p sash coord 1]
} -cleanup {
	deleteWindows
    deleteWindows
} -result {{0 0} {4 0}}
test panedwindow-11.13 {move sash in mapped window restricted to visible win} -setup {
	deleteWindows
    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]
            [frame .f3 -width 20 -height 30]
    place .p -width 50
    update
    .p sash place 1 100 0
    update
    .p sash coord 1
} -cleanup {
	deleteWindows
    deleteWindows
} -result {46 0}
test panedwindow-11.14 {move sash in mapped window restricted to visible win} -setup {
	deleteWindows
    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]
            [frame .f3 -width 20 -height 30]
    place .p -width 100
    update
    .p sash place 1 200 0
    update
    .p sash coord 1
} -cleanup {
	deleteWindows
    deleteWindows
} -result {96 0}
test panedwindow-11.15 {moving sash into "virtual" space on last pane increases reqsize} -setup {
	deleteWindows
    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]
            [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
    deleteWindows
} -result {68 100}


test panedwindow-12.1 {horizontal panedwindow lays out widgets properly} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 2 2 28 2 54 2]
test panedwindow-12.2 {vertical panedwindow lays out widgets properly} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 2 2 2 18 2 34]
test panedwindow-12.3 {horizontal panedwindow lays out widgets properly} -setup {
	deleteWindows
    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 ""
        .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
    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
    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
    deleteWindows
} -result [list 20 30]
test panedwindow-12.6 {panedwindow takes explicit widget width over reqwidth} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 20 20]
test panedwindow-12.7 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
    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
    deleteWindows
} -result {20 40}
test panedwindow-12.8 {horizontal panedwindow reqheight is max pane height} -setup {
	deleteWindows
    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
    deleteWindows
} -result {20 20}
test panedwindow-12.9 {panedwindow pane width overrides widget width} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 10 10]
test panedwindow-12.10 {panedwindow respects reqsize of panes when possible} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 20 30]
test panedwindow-12.11 {panedwindow takes explicit height over reqheight} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 20 20]
test panedwindow-12.12 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
    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
    deleteWindows
} -result {20 40}
test panedwindow-12.13 {vertical panedwindow reqwidth is max pane width} -setup {
	deleteWindows
    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
    deleteWindows
} -result {20 20}
test panedwindow-12.14 {panedwindow pane height overrides widget width} -setup {
	deleteWindows
    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
    deleteWindows
} -result [list 10 10]


test panedwindow-13.1 {PanestructureProc, widget yields managements} -setup {
	deleteWindows
    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
    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
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
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







-
+







-
+




-
+




-
+













-
+


-
+



-
+








-
+


-
+



-
+












-
+


-
+



-
+












-
+


-
+



-
+








-
+


-
+



-
+







-
+


-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+








-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+



-
-
+
+








-
+


-
+



-
-
+
+








-
+


-
+




-
+













-
+


-
+



-
+








-
+


-
+



-
+








-
+


-
+



-
+







-
+


-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+








-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+



-
-
+
+








-
+


-
+



-
-
+
+








-
+




-
+





-
+













-
+


-
+




-
+








-
+


-
+




-
+












-
+


-
+




-
+












-
+


-
+




-
+








-
+


-
+




-
+








-
+


-
+




-
+








-
+


-
+




-
+








-
+


-
+




-
-
+
+








-
+


-
+




-
-
+
+








-
+


-
+





-
+













-
+


-
+




-
+








-
+


-
+




-
+








-
+


-
+




-
+







-
+


-
+




-
+








-
+


-
+




-
+








-
+


-
+




-
-
+
+








-
+


-
+




-
-
+
+








-
+








-
+



-
+





-
+



-
+



-
+





-
+



-
+



-
+





-
+



-
+




-
+





-
+



-
+




-
+





-
+



-
+




-
+





-
+







    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
    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
    deleteWindows
} -result [list 20 40]


test panedwindow-17.1 {MoveSash, move right} -setup {
	deleteWindows
    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
        .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
    deleteWindows
} -result [list 42 42 {30 0}]
test panedwindow-17.2 {MoveSash, move right (unmapped) clipped by reqwidth} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 40 0]
test panedwindow-17.3 {MoveSash, move right (mapped, width < reqwidth) clipped by width} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 30 0]
test panedwindow-17.4 {MoveSash, move right (mapped, width > reqwidth) clipped by width} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 100 0]
test panedwindow-17.5 {MoveSash, move right respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 30 0]
test panedwindow-17.6 {MoveSash, move right respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 40 0]
test panedwindow-17.7 {MoveSash, move right pushes other sashes} -setup {
	deleteWindows
    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
        .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
    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
    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 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
    deleteWindows
} -result [list 50 0]
test panedwindow-17.10 {MoveSash, move right, negative minsize becomes 0} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list [list 50 0] [list 52 0]]
test panedwindow-17.11 {MoveSash, move left} -setup {
	deleteWindows
    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
        .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
    deleteWindows
} -result [list 42 42 {10 0}]
test panedwindow-17.12 {MoveSash, move left, can't move outside of window} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 0]
test panedwindow-17.13 {MoveSash, move left respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 10 0]
test panedwindow-17.14 {MoveSash, move left respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 22 0]
test panedwindow-17.15 {MoveSash, move left pushes other sashes} -setup {
	deleteWindows
    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
        .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
    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
    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 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
    deleteWindows
} -result [list 42 0]
test panedwindow-17.18 {MoveSash, move left, negative minsize becomes 0} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list [list 8 0] [list 10 0]]


test panedwindow-18.1 {MoveSash, move down} -setup {
	deleteWindows
    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
        .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
    deleteWindows
} -result [list 42 42 {0 30}]
test panedwindow-18.2 {MoveSash, move down (unmapped) clipped by reqheight} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 40]
test panedwindow-18.3 {MoveSash, move down (mapped, height < reqheight) clipped by height} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 30]
test panedwindow-18.4 {MoveSash, move down (mapped, height > reqheight) clipped by height} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 100]
test panedwindow-18.5 {MoveSash, move down respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 30]
test panedwindow-18.6 {MoveSash, move down respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 40]
test panedwindow-18.7 {MoveSash, move down pushes other sashes} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 62]
test panedwindow-18.8 {MoveSash, move down pushes other sashes, respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 52]
test panedwindow-18.9 {MoveSash, move down respects minsize, exludes pad} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 50]
test panedwindow-18.10 {MoveSash, move right, negative minsize becomes 0} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list [list 0 50] [list 0 52]]
test panedwindow-18.11 {MoveSash, move up} -setup {
	deleteWindows
    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
        .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
    deleteWindows
} -result [list 42 42 {0 10}]
test panedwindow-18.12 {MoveSash, move up, can't move outside of window} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 0]
test panedwindow-18.13 {MoveSash, move up respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 10]
test panedwindow-18.14 {MoveSash, move up respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 22]
test panedwindow-18.15 {MoveSash, move up pushes other sashes} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 0]
test panedwindow-18.16 {MoveSash, move up pushes other sashes, respects minsize} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 10]
test panedwindow-18.17 {MoveSash, move up respects minsize, exludes pad} -setup {
	deleteWindows
    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 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
    deleteWindows
} -result [list 0 42]
test panedwindow-18.18 {MoveSash, move up, negative minsize becomes 0} -setup {
	deleteWindows
    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 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
    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
    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]
        .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
    deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.2 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
    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]
        .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
    deleteWindows
} -result [list [list 60 20] [list 60 40]]

test panedwindow-19.3 {ComputeGeometry, reqheight taken from widgets} -setup {
	deleteWindows
    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
        .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
    deleteWindows
} -result [list [list 60 60] [list 60 80]]

test panedwindow-19.4 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
    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]
        .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
    deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.5 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
    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]
        .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
    deleteWindows
} -result [list [list 20 60] [list 40 60]]

test panedwindow-19.6 {ComputeGeometry, reqwidth taken from widgets} -setup {
	deleteWindows
    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
        .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
    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
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
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







-
+






-
+


-
+



-
+








-
+



-
+







-
+




-
+







-
+



-
+





-
+


-
+



-
+





-
+


-
+




-
+





-
+


-
+



-
+







-
+




-
+







-
+



-
+







-
+


-
+



-
+







-
+


-
+



-
+







-
+


-
+



-
+







-
+




-
+







-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+




-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+




-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+




-
+




-
+


-
+









-
+




-
+




-
+


-
+




-
+


-
+






-
+


-
+






-
+


-
+






-
+


-
+






-
+


-
+






-
+


-
+






-
+


-
+





-
+


-
+













-
+



-
+





-
+

-
+


-
+







-
+


-
+










-
+


-
+











-
+


-
+











-
+


-
+











-
+


-
+











-
+


-
+











-
+


-
+











-
+


-
+











-
+


-
+











-
+


-
+











-
+


-
+












-
+


-
+





-
+


-
+






-
+


-
+






-
+


-
+





-
+


-
+








-
+


-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+











-
-
-
-
+
+
+
+

-
-
-
+
+
+

-
-
-
+
+
+

-
-
-
+
+
+




-
+

-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+





-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+





-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+
















-
+




-
+




-
+


-
+







    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
    deleteWindows
} -body {
    panedwindow .p
    .p add [frame .f -width 20 -height 20 -bg blue]
    destroy .f
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-20.2 {destroyed pane causes geometry recomputation} -setup {
	deleteWindows
    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]
            [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
    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
            [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
    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
            [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
    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 ""
            [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
    deleteWindows
} -result {10 15}
test panedwindow-21.4 {ArrangePanes, panes clipped by size of pane} -setup {
	deleteWindows
    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]
            [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
    deleteWindows
} -result {10 20}
test panedwindow-21.5 {ArrangePanes, panes clipped by size of pane} -setup {
	deleteWindows
    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]
            [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
    deleteWindows
} -result {20 10}
test panedwindow-21.6 {ArrangePanes, height of pane taken from total height} -setup {
	deleteWindows
    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 ""
            [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
    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 ""
            [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
    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]
            [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
    deleteWindows
} -result {1 0}
test panedwindow-21.9 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
    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]
            [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
    deleteWindows
} -result {1 0}
test panedwindow-21.10 {ArrangePanes, panes with width <= 0 are unmapped} -setup {
	deleteWindows
    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]
            [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
    deleteWindows
} -result {1 0}
test panedwindow-21.11 {ArrangePanes, last pane shrinks} -setup {
	deleteWindows
    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
            [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
    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
            [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
    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]
    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
    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]
    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
    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]
    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
    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]
            [frame .f2 -width 20 -height 40 -bg red]
    set result [winfo reqheight .p]
    .f1 configure -height 80
    lappend result [winfo reqheight .p]
} -cleanup {
	deleteWindows
    deleteWindows
} -result {40 80}
test panedwindow-22.2 {PanedWindowReqProc, react to pane geometry changes} -setup {
	deleteWindows
    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
    deleteWindows
} -result 10


test panedwindow-23.1 {ConfigurePanes, can't add panedwindow to itself} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add .p
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {can't add .p to itself}
test panedwindow-23.2 {ConfigurePanes, bad window throws error} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add .b
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {bad window path name ".b"}
test panedwindow-23.3 {ConfigurePanes, bad window aborts processing} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b .a}
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-23.4 {ConfigurePanes, bad option aborts processing} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    button .b
    catch {.p add .b -sticky foobar}
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-23.5 {ConfigurePanes, after win isn't managed by panedwin} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -after .c
} -cleanup {
	deleteWindows
    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
    deleteWindows
} -body {
    panedwindow .p
    button .b
    button .c
    .p add .b -before .c
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {window ".c" is not managed by .p}
test panedwindow-23.7 {ConfigurePanes, -after {} is a no-op} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -after {}
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {.b .c}
test panedwindow-23.8 {ConfigurePanes, -before {} is a no-op} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p paneconfigure .b -before {}
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {.b .c}
test panedwindow-23.9 {ConfigurePanes, new panes are added} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b] [button .c]
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {.b .c}
test panedwindow-23.10 {ConfigurePanes, options applied to all panes} -setup {
	deleteWindows
    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
    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
    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]
            [.p panecget .c -sticky] [.p panecget .c -height]
} -cleanup {
	deleteWindows
    deleteWindows
} -result [list {.b .c} es 2 es 2]
test panedwindow-23.12 {ConfigurePanes, widgets added to end by default} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p add [button .b]
    .p add [button .c]
    .p add [button .d]
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {.b .c .d}
test panedwindow-23.13 {ConfigurePanes, -after, single addition} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    button .a
    button .b
    button .c

    .p add .a .b
    .p add .c -after .a
    .p panes
} -cleanup {
	deleteWindows
    deleteWindows
} -result {.a .c .b}
test panedwindow-23.14 {ConfigurePanes, -after, multiple additions} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.a .c .d .b}
test panedwindow-23.15 {ConfigurePanes, -after, relocates existing widget} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.a .d .b .c}
test panedwindow-23.16 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.a .b .d .c}
test panedwindow-23.17 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.b .d .a .c}
test panedwindow-23.18 {ConfigurePanes, -after, relocates existing widgets} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.19 {ConfigurePanes, -after, after last window} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.a .b .c .d}
test panedwindow-23.20 {ConfigurePanes, -before, before first window} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.d .a .b .c}
test panedwindow-23.21 {ConfigurePanes, -before, relocate existing windows} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.d .b .a .c}
test panedwindow-23.22 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.a .b .c}
test panedwindow-23.23 {ConfigurePanes, pane specified multiple times} -setup {
	deleteWindows
    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
    deleteWindows
} -result {.c .a .b}
test panedwindow-23.24 {ConfigurePanes, panedwindow cannot manage toplevels} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    toplevel .t
    .p add .t
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {can't add toplevel .t to .p}
test panedwindow-23.25 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    frame .f
    button .f.b
   .p add .f.b
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {can't add .f.b to .p}
test panedwindow-23.26 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
    deleteWindows
} -body {
    frame .f
    panedwindow .f.p
    button .b
    .f.p add .b
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-23.27 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    button .p.b
    .p add .p.b
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-23.28 {ConfigurePanes, restrict possible panes} -setup {
	deleteWindows
    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
    deleteWindows
} -result {}
test panedwindow-23.29 {ConfigurePanes, -hide works} -setup {
	deleteWindows
    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]
    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
    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]
    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
    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]]
    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]]
    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]]
    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]]
    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
    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
    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
    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]
    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
    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]
    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
    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]
    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
    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]
    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
    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]
    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
    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
    deleteWindows
} -result {.pw.l3 {} .pw.l1}


test panedwindow-25.1 {DestroyPanedWindow} -setup {
	deleteWindows
    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]
        .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
        destroy $w
    }
    set result {}
} -result {}
test panedwindow-25.2 {UnmapNotify and MapNotify events are propagated to panes} -setup {
    deleteWindows
} -body {
    panedwindow .pw
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
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







-
+




-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+


-
+

-
+


-
+


-
+


-
+

-
+


-
+


-
+


-
+

-
+


-
+


-
+


-
+

-
+


-
+


-
+



-
-
+
+


-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+



-
+


-
+


-
+


-
+

-
+


-
+


-
+


-
+

-
+


-
+


-
+


-
+

-
+


-
+


-
+


-
+

-
+


-
+


-
+



-
-
+
+


-
+




-
+



-
+


-
+






-
+




-
+







    pack .pw
    update
    lappend result [winfo ismapped .pw]
    lappend result [winfo ismapped .pw.b]
    destroy .pw .pw.b
    set result
} -cleanup {
	deleteWindows
    deleteWindows
} -result {1 0 0 1 1}


test panedwindow-26.1 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-26.2 {PanedWindowIdentifyCoords, padding is included} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.3 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.4 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 24 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.5 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.6 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 -1
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-26.7 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 26 100
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-26.8 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
            -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 4
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.9 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6
            -handlesize 6
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 22 5
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 handle}
test panedwindow-26.10 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
            -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 5
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 handle}
test panedwindow-26.11 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8
            -handlesize 8
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 20 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.12 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20] \
            [frame .f3 -bg green -width 20 -height 20]
    .p identify 48 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {1 sash}
test panedwindow-26.13 {identify subcommand errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -borderwidth 0 -sashpad 2 -sashwidth 4
    .p identify
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {wrong # args: should be ".p identify x y"}
test panedwindow-26.14 {identify subcommand errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p identify foo bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "foo"}
test panedwindow-26.15 {identify subcommand errors} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p
    .p identify 0 bar
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {expected integer but got "bar"}
test panedwindow-26.16 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 0
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-26.17 {PanedWindowIdentifyCoords, padding is included} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.18 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 22
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.19 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 24
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.20 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 26
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.21 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify -1 26
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-26.22 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 100 26
} -cleanup {
	deleteWindows
    deleteWindows
} -result {}
test panedwindow-26.23 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
            -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 4 22
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.24 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 6 -orient vertical
            -handlesize 6 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 22
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 handle}
test panedwindow-26.25 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
            -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 5 20
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 handle}
test panedwindow-26.26 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bd 0 -sashwidth 2 -sashpad 2 -showhandle 1 -handlepad 5 \
	    -handlesize 8 -orient vertical
            -handlesize 8 -orient vertical
    .p add [frame .f -bg red -width 20 -height 20] \
	    [frame .f2 -bg blue -width 20 -height 20]
            [frame .f2 -bg blue -width 20 -height 20]
    .p identify 0 20
} -cleanup {
	deleteWindows
    deleteWindows
} -result {0 sash}
test panedwindow-26.27 {PanedWindowIdentifyCoords} -setup {
	deleteWindows
    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]
            [frame .f2 -bg blue -width 20 -height 20] \
            [frame .f3 -bg green -width 20 -height 20]
    .p identify 0 48
} -cleanup {
	deleteWindows
    deleteWindows
} -result {1 sash}


test panedwindow-27.1 {destroy the window cleanly on error [Bug #616589]} -setup {
	deleteWindows
    deleteWindows
} -body {
    panedwindow .p -bogusopt bogus
} -cleanup {
	deleteWindows
    deleteWindows
} -returnCodes error -result {unknown option "-bogusopt"}
test panedwindow-27.2 {destroy the window cleanly on rename [Bug #616589]} -setup {
	deleteWindows
    deleteWindows
} -body {
    destroy .p
    panedwindow .p
    rename .p {}
    winfo exists .p
} -cleanup {
	deleteWindows
    deleteWindows
} -result 0


test panedwindow-28.1 {resizing width} -setup {
	deleteWindows
    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
5484
5485
5486
5487
5488
5489
5490
5491

5492
5493
5494
5495
5496
5497
5498
5484
5485
5486
5487
5488
5489
5490

5491
5492
5493
5494
5495
5496
5497
5498







-
+







    update
    set b "$a [winfo width .f2]"
} -cleanup {
    deleteWindows
} -result {100 110}

test panedwindow-28.2 {resizing height} -setup {
	deleteWindows
    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
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
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







-
+

-
-
-
-
-
+
+
+
+
+








-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+










    deleteWindows
} -result {100 110}


test panedwindow-29.1 {display on depths other than the default one} -constraints {
    pseudocolor8 haveTruecolor24
} -setup {
	deleteWindows
    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
    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
    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


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
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 "place" command.  It is
# organized in the standard fashion for Tcl tests.
#
# Copyright © 1995 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
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
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123

124
125
126
127
128

129
130
131
132
133
134

135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122

123
124
125
126
127

128
129
130
131
132
133

134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150







-
+












-
+




-
+




-
+





-
+








-
+







} -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}
} -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}
} -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 "."}
} -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}
} -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}
} -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}
} -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 {
257
258
259
260
261
262
263
264
265
266



267
268
269



270
271



272
273
274
275
276
277
278

279
280
281
282
283

284
285
286

287
288
289
290
291
292
293
294
295
296

297
298
299
300
301

302
303
304

305
306
307
308
309
310
311
257
258
259
260
261
262
263



264
265
266



267
268
269


270
271
272
273
274
275
276
277
278

279
280
281
282
283

284
285
286

287
288
289
290
291
292

293
294
295

296
297
298
299
300

301
302
303

304
305
306
307
308
309
310
311







-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
+






-
+




-
+


-
+





-



-
+




-
+


-
+







} -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
# Tests place-8.1 and place-8.2 are constrained with failsOnUbuntu
# because they are failing in the GitHub CI environment, using Linux Ubuntu.
# These tests are also constrained with failsOnXQuarz because they fail
    }
} else {
    proc placeUpdate {} {
# on macOS when building with clang --disable-aqua (which uses XQuartz)
# (this is the case both at GitHub CI and on a real Mac).
# Analysis shows that, on both cases, WaitForMapNotify is giving up on
    }
}
# waiting for the MapNotify event that should show up when running
# 'wm iconify'. The timeout delay (2s) is exceeded without the unmapping
# having happened. The cause for this is unknown (see comments in WaitForMapNotify).

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
    update
    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
    update
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    placeUpdate
    update
    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
    update
    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
    update
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    placeUpdate
    update
    lappend result [winfo ismapped .t.f2]
} -result {1 0 42 32 0 1}
destroy .t


test place-9.1 {PlaceObjCmd} -body {
    place
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342







-
+







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}
} -returnCodes error -result {bad option "badopt": must be configure, content, forget, info, or slaves}
test place-9.6 {PlaceObjCmd, configure errors} -setup {
    destroy .foo
} -body {
    frame .foo
    place configure .foo
} -cleanup {
    destroy .foo
503
504
505
506
507
508
509
510
511


512
513
514



515
516
517
518
519




520
521
522
523
524
525
526
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







-
-
+
+

-
-
+
+
+

-
-
-
-
+
+
+
+







        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}]
	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}]
	pack .f.f
	update; # Needed because of TIP #518, handle <<NoManagedChild>> event.
    } {
        place .f.f -x [expr {1 + 1}] -y [expr {2 + 2}]
        destroy .f
        frame .f
        frame .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}

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
1
2
3
4
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 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.
# Copyright (c) 1993-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
    destroy {*}[winfo children .raise]
        }
    update idletasks
    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
Changes to tests/safe.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

137
138
139
140
141
142
143
144

145
146
147
148
149
150

151
152
153
154
155
156
157
137
138
139
140
141
142
143

144
145
146
147
148
149

150
151
152
153
154
155
156
157







-
+





-
+







} -result {ok {appname not accessible in a safe interpreter}}
test safe-2.4 {Unsafe subcommands not available} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status broken
    if {[catch {interp eval a {tk scaling}} msg]} {
    if {[catch {interp eval a {tk scaling 1}} msg]} {
	set status ok
    }
    list $status $msg
} -cleanup {
    safe::interpDelete a
} -result {ok {scaling not accessible in a safe interpreter}}
} -result {ok {setting the scaling not accessible in a safe interpreter}}

test safe-3.1 {Unsafe commands are available hidden} -setup {
    catch {safe::interpDelete a}
} -body {
    safe::interpCreate a
    safe::loadTk a
    set status ok
Changes to tests/safePrimarySelection.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

Changes to tests/scale.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

324
325
326
327
328
329
330
331

332
333
334
335
336
337
338

339
340
341
342
343
344
345
324
325
326
327
328
329
330

331
332
333
334
335
336
337

338
339
340
341
342
343
344
345







-
+






-
+







    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 .
    winfo children .
} -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 .
    winfo children .
} -result {}


# Widget used in 3.* tests
destroy .s
scale .s -from 100 -to 200
pack .s
1087
1088
1089
1090
1091
1092
1093
1094

1095
1096
1097
1098
1099
1100
1101
1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
1101







-
+







        set traceInfo $args
    }
    .s configure -from 0 -to 100 -command {set x} -variable y
    update

    .s set 50
    update
    trace variable y w varTrace
    trace add variable y write varTrace
    set traceInfo empty
    set x untouched
    .s set 50
    update
    list $x $traceInfo
} -result {untouched empty}

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
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







-
+




















-
+










+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+















-
+


-
+


-
+


-
+







    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 <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 <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-18.4 {Bug [415415ffff] - Long callback: One click -> Several steps} -setup {
    catch {destroy .s}
    scale .s -from 0 -to 5 -resolution 1 -variable x1 -orient horizontal -length 100 \
            -command longCmd -repeatdelay 300
    pack .s
    update
    proc longCmd {unused} {
      after 500  ; # larger than -repeatdelay
    }
} -body {
    foreach {x y} [.s coord 50] {}
    event generate .s <Button-1> -x $x -y $y
    update
    event generate .s <ButtonRelease-1> -x $x -y $y
    update
    set x1
} -cleanup {
    destroy .s
} -result {1}

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 <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 <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 <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 <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
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
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







-


-

+
+

+



-

+








+














+
















+
















+







    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
    update idletasks
    .s set 10
    set timeout [after 500 {set $commandedVar "timeout"}]
    set commandedVar -1
    vwait commandedVar  ; # -command callback shall fire
    set res [list [.s get] $commandedVar]
} -cleanup {
    destroy .s
    after cancel $timeout
    destroy .s
} -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
    update idletasks
    .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
    update idletasks
    .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
    update idletasks
    .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
    update idletasks
    .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
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
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 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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]} {
270
271
272
273
274
275
276
277

278

279

280
281
282
283

284
285


286
287
288
289
290
291
292
266
267
268
269
270
271
272

273
274
275

276
277
278
279

280
281

282
283
284
285
286
287
288
289
290







-
+

+
-
+



-
+

-
+
+







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} {
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 179]
} [format %.6g [expr {(179.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
} 1
       /([getTroughSize .s] - 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} {
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 178]
} {0.993711}
} [format %.6g [expr {(178.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)}]]
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

314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326







-
+







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 {
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] {
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371







-
+
















-
+







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
    # macOS aqua 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
    # macOS aqua 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
399
400
401
402
403
404
405
406

407
408
409

410
411
412

413
414
415

416
417
418

419
420
421
422

423
424
425
426

427
428
429
430
431
432

433
434
435

436
437
438
439
440
441
442
397
398
399
400
401
402
403

404
405
406

407
408
409

410
411
412

413
414
415

416
417
418
419

420
421
422
423

424
425
426
427
428
429

430
431
432

433
434
435
436
437
438
439
440







-
+


-
+


-
+


-
+


-
+



-
+



-
+





-
+


-
+







    .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 {
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} nodeprecated {
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} nodeprecated {
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} nodeprecated {
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} nodeprecated {
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} nodeprecated {
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} nodeprecated {
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"}}
} {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"}}
} {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 {ambiguous option "c": must be activate, cget, configure, delta, fraction, get, identify, or set}}

488
489
490
491
492
493
494
495

496
497
498
499




500
501
502
503


504
505
506
507
508
509
510
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







-
+


-
-
+
+
+
+


-
-
+
+







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
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 8 4
} {trough1}
test scrollbar-6.12.1 {ScrollbarPosition procedure} {x11 failsOnUbuntu failsOnXQuarz} {
    .s identify 8 19
test scrollbar-6.12.1 {ScrollbarPosition procedure} x11 {
    # x11 scrollbars have arrows 19 pixels height,
    # but on XQuartz they are 15 pixels height
    .s identify 8 15
} {arrow1}
test scrollbar-6.12.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 19
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 8 15
} {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}
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
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







-
-
+
+
+
+


-
-
+
+





-
+












-
-
+
+
+
+
+




















-
+









-
+






-
-
+
+
+
+
+







    .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
test scrollbar-6.29.1 {ScrollbarPosition procedure} x11 {
    # x11 scrollbars have arrows at least 19 pixels height
    # but on XQuartz they are 15 pixels height
    .s identify 8 184
} {arrow2}
test scrollbar-6.29.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 180
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 8 184
} {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
    # macOS aqua 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
test scrollbar-6.35 {ScrollbarPosition procedure} unix {
    # Linux x11 scrollbars have arrows 18 pixels width
    # macOS XQuartz scrollbars have arrows 14 pixels width
    # macOS aqua scrollbars have no arrows nowadays
    .s identify 14 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
    # macOS aqua 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
    # macOS aqua 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
test scrollbar-6.44 {ScrollbarPosition procedure} unix {
    # Linux x11 scrollbars have arrows 18 pixels height
    # macOS XQuartz scrollbars have arrows 14 pixels height
    # macOS aqua scrollbars have no arrows nowadays
    .t.s identify 100 14
} {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
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
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







-
+




















-
+


















-
+













+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+













-
+







-
+














-
+



-
+














-
+



-
+











    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.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} 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.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} -setup {
test scrollbar-10.1.1 {<MouseWheel> event on scrollbar} -constraints {notAqua} -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.1.2 {<MouseWheel> event on scrollbar} -constraints {aqua} -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 -4
    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 {
test scrollbar-10.2.1 {<MouseWheel> event on scrollbar} -constraints {notAqua} -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 {
test scrollbar-10.2.2 {<MouseWheel> event on scrollbar} -constraints {aqua} -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
    event generate .s <Shift-MouseWheel> -delta -4
    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}
    bind .top.s <2> {destroy_scrollbar}
    pack .top.s
    focus -force .top.s
    update
    event generate .top.s <Button-2>
    event generate .top.s <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}
    bind .top.s <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}]
    event generate .top.s <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
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
1
2
3
4


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33




-
-
+
+



















-
+







# 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.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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)]}]
testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]

global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {
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
1
2
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 © 1994 Sun Microsystems, Inc.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright © 2001 by ActiveState Corporation.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 2001 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)]}]
testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# 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
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308







-
+







} {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} {
test send-8.16 {Tk_SendCmd procedure, bogusCommWindow} {secureserver testsend failsOnUbuntu failsOnXQuarz} {
    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"}}

437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
438
439
440
441
442
443
444



445



446
447
448
449
450
451



452


453
454
455
456
457
458
459







-
-
-
+
-
-
-






-
-
-
+
-
-







}
test send-10.8 {SendEventProc procedure, exceptional return} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-r $id 62\n-s break\n"
    update
    testsend prop [winfo id .f] Comm
} {
r
-s 62
} "\nr\n-s 62\n-r \n-c 3\n"
-r 
-c 3
}
test send-10.9 {SendEventProc procedure, empty return} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-r $id 62\n-s concat\n"
    update
    testsend prop [winfo id .f] Comm
} {
r
-s 62
} "\nr\n-s 62\n-r \n"
-r 
}
test send-10.10 {SendEventProc procedure, asynchronous calls} {secureserver testsend} {
    testsend prop [winfo id .f] Comm {}
    testsend prop comm Comm \
	    "c\n-n tktest\n-s foreach i {1 2 3} {error {test error} {Initial errorInfo} {test code}}\n"
    update
    testsend prop [winfo id .f] Comm
} {}
519
520
521
522
523
524
525
526

527
528
529


530
531
532
533
534
535
536
511
512
513
514
515
516
517

518
519


520
521
522
523
524
525
526
527
528







-
+

-
-
+
+







    setupbg
    dobg {tk appname t_s_3}
    set x [list [catch {send t_s_3 exit} msg] $msg]
    cleanupbg
    set x
} {1 {target application died}}

test send-11.1 {AppendPropCarefully and AppendErrorProc procedures} {secureserver testsend} {
test send-11.1 {AppendPropCarefully and AppendErrorProc procedures} -constraints {secureserver testsend} -body {
    testsend prop root InterpRegistry "0x21447 dummy\n"
    list [catch {send dummy foo} msg] $msg
} {1 {no application named "dummy"}}
    send dummy foo
} -returnCodes 1 -match regexp -result {^(target application died|no application named "dummy")$}
test send-11.2 {AppendPropCarefully and AppendErrorProc procedures} {secureserver testsend} {
    testsend prop comm Comm "c\n-r0x123 44\n-n tktest\n-s concat a b c\n"
    update
} {}

winfo interps
tk appname tktest
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
1
2
3



4
5
6
7
8
9
10
11
12
13



14
15
16
17
18
19

20
21
22
23
24
25
26
27



-
-
-
+
+
+







-
-
-






-
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
# For trace add 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} {
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -activebackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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 {
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
78
79
80
81
82
83
84

85
86
87
88
89
90
91
92







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -background non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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 {
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -bd badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}
} -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 {
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -bg non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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 {
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -borderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}
} -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 {
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -buttonbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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 {
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -buttoncursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}
} -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 {
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -cursor badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad cursor spec "badValue"}
} -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 {
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -disabledbackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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 {
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -disabledforeground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}
} -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 {
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -exportselection xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}
} -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 {
313
314
315
316
317
318
319
320

321
322
323
324
325
326
327
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -fg bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}
} -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 {
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
332
333
334
335
336
337
338

339
340
341
342
343
344
345
346







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -font {}
} -cleanup {
    destroy .e
} -returnCodes {error} -result {font "" doesn't exist}
} -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 {
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -foreground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}
} -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 {
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -format %d
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad spinbox format specifier "%d"}
} -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 {
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
398
399
400
401
402
403
404

405
406
407
408
409
410
411
412







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -from bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected floating-point number but got "bogus"}
} -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 {
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightbackground ugly
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "ugly"}
} -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 {
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightcolor bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}
} -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 {
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -highlightthickness bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "bogus"}
} -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 {
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -increment bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected floating-point number but got "bogus"}
} -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 {
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertbackground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}
} -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 {
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559
542
543
544
545
546
547
548

549
550
551
552
553
554
555
556







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertborderwidth 2.6x
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "2.6x"}
} -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 {
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
564
565
566
567
568
569
570

571
572
573
574
575
576
577
578







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertofftime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}
} -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 {
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -insertontime 3.2
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3.2"}
} -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 {
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
632
633
634
635
636
637
638

639
640
641
642
643
644
645
646







-
+







        -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}
} -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 {
657
658
659
660
661
662
663
664

665
666
667
668
669
670
671
654
655
656
657
658
659
660

661
662
663
664
665
666
667
668







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -readonlybackground non-existent
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "non-existent"}
} -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 {
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
676
677
678
679
680
681
682

683
684
685
686
687
688
689
690







-
+







        -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}
} -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 {
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
698
699
700
701
702
703
704

705
706
707
708
709
710
711
712







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -repeatdelay 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}
} -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 {
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
720
721
722
723
724
725
726

727
728
729
730
731
732
733
734







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -repeatinterval 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}
} -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 {
745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectbackground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}
} -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 {
767
768
769
770
771
772
773
774

775
776
777
778
779
780
781
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectborderwidth badValue
} -cleanup {
    destroy .e
} -returnCodes {error} -result {bad screen distance "badValue"}
} -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 {
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
786
787
788
789
790
791
792

793
794
795
796
797
798
799
800







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -selectforeground bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {unknown color name "bogus"}
} -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 {
811
812
813
814
815
816
817
818

819
820
821
822
823
824
825
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822







-
+







        -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}
} -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 {
857
858
859
860
861
862
863
864

865
866
867
868
869
870
871
854
855
856
857
858
859
860

861
862
863
864
865
866
867
868







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -to bogus
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected floating-point number but got "bogus"}
} -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 {
879
880
881
882
883
884
885
886

887
888
889
890
891
892
893
876
877
878
879
880
881
882

883
884
885
886
887
888
889
890







-
+







        -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}
} -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 {
913
914
915
916
917
918
919
920

921
922

923
924
925
926
927
928
929


930
931
932
933
934
935
936
910
911
912
913
914
915
916

917
918

919
920
921
922
923
924


925
926
927
928
929
930
931
932
933







-
+

-
+





-
-
+
+







        -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}
} -returnCodes error -result {list element in braces followed by "list" instead of space}

test spinbox-1.80 {configuration option: "vcmd"} -setup {
test spinbox-1.80 {configuration option: "validatecommand"} -setup {
        spinbox .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12} \
        -relief sunken
    pack .e
    update
} -body {
    .e configure -vcmd "a command"
    .e cget -vcmd
    .e configure -validatecommand "a command"
    .e cget -validatecommand
} -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
947
948
949
950
951
952
953
954

955
956
957
958
959
960
961
944
945
946
947
948
949
950

951
952
953
954
955
956
957
958







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -width 3p
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected integer but got "3p"}
} -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 {
969
970
971
972
973
974
975
976

977
978
979
980
981
982
983
966
967
968
969
970
971
972

973
974
975
976
977
978
979
980







-
+







        -relief sunken
    pack .e
    update
} -body {
    .e configure -wrap xyzzy
} -cleanup {
    destroy .e
} -returnCodes {error} -result {expected boolean value but got "xyzzy"}
} -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 {
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
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







-
+












-
+







	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 insert 0 "ab\u4e4e"
    .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 "abc"
    .e insert 0 "ab\u4e4ec"
    .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
1121
1122
1123
1124
1125
1126
1127
1128

1129
1130
1131
1132
1133
1134
1135
1118
1119
1120
1121
1122
1123
1124

1125
1126
1127
1128
1129
1130
1131
1132







-
+







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 "abcdefghijklmnop"
    .e insert 0 "abcdefghij\u4e4eklmnop"
    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 {
1163
1164
1165
1166
1167
1168
1169
1170

1171
1172
1173
1174
1175
1176
1177
1160
1161
1162
1163
1164
1165
1166

1167
1168
1169
1170
1171
1172
1173
1174







-
+







    spinbox .e
    pack .e
    update
} -body {
    llength [.e configure]
} -cleanup {
    destroy .e
} -result 51
} -result 49
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"}
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
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







-
+



-
+



-
+




-
+







test spinbox-3.24 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
    set x {}
} -body {
# UTF
    .e insert end "0123467890"
    .e insert end "01234\u4e4e67890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123457890"
    .e insert end "012345\u4e4e7890"
    .e delete 6
    lappend x [.e get]
    .e delete 0 end
    .e insert end "0123456890"
    .e insert end "0123456\u4e4e890"
    .e delete 6
    lappend x [.e get]
} -cleanup {
    destroy .e
} -result [list "012347890" "0123457890" "012345890"]
} -result [list "01234\u4e4e7890" "0123457890" "012345\u4e4e890"]
test spinbox-3.25 {SpinboxWidgetCmd procedure, "delete" widget command} -setup {
    spinbox .e
    pack .e
    update
} -body {
    .e insert end "01234567890"
    .e delete 6 5
1352
1353
1354
1355
1356
1357
1358
1359

1360
1361
1362
1363
1364
1365
1366
1349
1350
1351
1352
1353
1354
1355

1356
1357
1358
1359
1360
1361
1362
1363







-
+







} -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
    .e insert 0 abc\u4e4e\u0153def
    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 {
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
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







-
+










-
+







    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"}
} -returnCodes error -result {wrong # args: should be ".e xview scroll number units|pages"}
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"}
} -returnCodes error -result {expected integer 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
1850
1851
1852
1853
1854
1855
1856
1857

1858
1859
1860
1861
1862
1863
1864
1847
1848
1849
1850
1851
1852
1853

1854
1855
1856
1857
1858
1859
1860
1861







-
+







} -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}
} -returnCodes error -result {bad argument "foobars": must be units or pages}
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
1894
1895
1896
1897
1898
1899
1900
1901

1902
1903
1904
1905
1906
1907
1908
1891
1892
1893
1894
1895
1896
1897

1898
1899
1900
1901
1902
1903
1904
1905







-
+







} -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 
    .e insert 10 \u4e4e
    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]]
1951
1952
1953
1954
1955
1956
1957
1958

1959
1960
1961
1962
1963
1964

1965
1966
1967
1968
1969
1970
1971
1948
1949
1950
1951
1952
1953
1954

1955
1956
1957
1958
1959
1960

1961
1962
1963
1964
1965
1966
1967
1968







-
+





-
+







} -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
    trace add variable x write override
    .e insert 0 "Some text"
    .e configure -textvariable x
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
    trace remove variable x write override
} -result {12345 12345}

test spinbox-5.5 {ConfigureSpinbox procedure} -setup {
    set x {}
    spinbox .e1
    spinbox .e2
} -body {
2013
2014
2015
2016
2017
2018
2019
2020
2021


2022
2023

2024
2025
2026
2027
2028

2029
2030
2031
2032
2033
2034
2035
2010
2011
2012
2013
2014
2015
2016


2017
2018
2019

2020
2021
2022
2023


2024
2025
2026
2027
2028
2029
2030
2031







-
-
+
+

-
+



-
-
+








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}}]
    update
    set scrollInfo wrong
    .e configure -width 5
    vwait scrollInfo
    update
    format {%.6f %.6f} {*}$scrollInfo
} -cleanup {
    destroy .e
    after cancel $timeout
} -result {0.000000 0.363636}
} -result {0.000000 0.454545}

test spinbox-5.8 {ConfigureSpinbox procedure} -constraints {
    fonts
} -setup {
    spinbox .e -borderwidth 2 -highlightthickness 2
    pack .e
} -body {
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
2071
2072
2073
2074
2075
2076
2077















2078
2079
2080
2081
2082
2083
2084







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







# 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
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
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







-
-
+
+

-
+



-










-
-
+
+

-
+



-







    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}}]
    update
    set scrollInfo wrong
    .e insert 2 XXX
    vwait scrollInfo
    update
    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}}]
    update
    set scrollInfo wrong
    .e insert 500 XXX
    vwait scrollInfo
    update
    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
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
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







-
-
+
+

-
+



-









-
-
+
+

-
+



-









-
-
+
+

-
+



-







    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}}]
    update
    set scrollInfo wrong
    .e delete 2 4
    vwait scrollInfo
    update
    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}}]
    update
    set scrollInfo wrong
    .e delete -1 2
    vwait scrollInfo
    update
    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}}]
    update
    set scrollInfo wrong
    .e delete 3 1000
    vwait scrollInfo
    update
    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
2617
2618
2619
2620
2621
2622
2623
2624

2625
2626
2627
2628
2629
2630
2631
2593
2594
2595
2596
2597
2598
2599

2600
2601
2602
2603
2604
2605
2606
2607







-
+







    .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 {
test spinbox-8.18 {DeleteChars procedure} -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
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
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







-
+




-
+





-
+







                          + 2 * ( [.e cget -borderwidth] + \
                                [.e cget -highlightthickness] + $XPAD ) \
                          + $buttonWidth } ]
    expr {[winfo reqwidth .e] == $expected}
} -cleanup {
    destroy .e
    unset XPAD buttonWidth expected
} -result 1
} -result {1}

test spinbox-9.1 {SpinboxValueChanged procedure} -setup {
    unset -nocomplain x
} -body {
    trace variable x w override
    trace add variable x write override
    spinbox .e -textvariable x -width 0
    .e insert 0 foo
    list $x [.e get]
} -cleanup {
    destroy .e
    trace vdelete x w override
    trace remove variable x write 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
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
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







-
-
+
+


-
+



-





-
-
+
+

-
+



-




-
-
+
+


-
+



-









-
+
+

-
+







    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}}]
    update
    set scrollInfo wrong
    .e delete 0 end
    .e insert 0 123
    vwait scrollInfo
    update
    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}}]
    update
    set scrollInfo wrong
    .e xview 3
    vwait scrollInfo
    update
    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}}]
    update
    set scrollInfo wrong
    .e insert 0 abcdefghijklmnopqrs
    .e xview
    vwait scrollInfo
    update
    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
    update
    set scrollInfo wrong
    .e configure -xscrollcommand thisisnotacommand
    vwait x
    update
    list $x $errorInfo
} -cleanup {
    destroy .e
    rename bgerror {}
} -result {{invalid command name "thisisnotacommand"} {invalid command name "thisisnotacommand"
    while executing
"thisisnotacommand 0.0 1.0"
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
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







-
+





-
+





-
+







    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"}
}  -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"}
}  -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"}
}  -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 {
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
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







-
+









-
-
-
-
+
+
+
+








-
+
+
+
+
+
+
+
+
+
+
+
+
+
+







} -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
    trace add variable myvar write 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!}]
} -match glob -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}
} -match glob -result {can*t trace "thisnsdoesntexist::myvar": parent namespace does*t exist}
test spinbox-25.3 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [spinbox .s]
    update
} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    .s get
} -cleanup {
    destroy .s
} -result {A sample }

# 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
Deleted tests/teapotTransparent.png.

cannot compute difference between binary files

Changes to tests/text.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# This file is a Tcl script to test the code in the file tkText.c.
# This file is organized in the standard fashion for Tcl tests.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436







-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+







    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -autoseparators nah
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.3 {configuration option: "background"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -background #ff00ff
    .t cget -background
} -cleanup {
    destroy .t
} -result {#ff00ff}
test text-1.4 {configuration option: "background"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -background <gorp>
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.5 {configuration option: "bd"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bd 4
    .t cget -bd
} -cleanup {
    destroy .t
} -result 4
test text-1.6 {configuration option: "bd"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bd foo
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.7 {configuration option: "bg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bg blue
    .t cget -bg
} -cleanup {
    destroy .t
} -result {blue}
test text-1.8 {configuration option: "bg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -bg #xx
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.9 {configuration option: "blockcursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -blockcursor 0
    .t cget -blockcursor
} -cleanup {
    destroy .t
} -result 0
test text-1.10 {configuration option: "blockcursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -blockcursor xx
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.11 {configuration option: "borderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -borderwidth 7
    .t cget -borderwidth
} -cleanup {
    destroy .t
} -result 7
test text-1.12 {configuration option: "borderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -borderwidth ++
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.13 {configuration option: "cursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -cursor watch
    .t cget -cursor
} -cleanup {
    destroy .t
} -result {watch}
test text-1.14 {configuration option: "cursor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -cursor lousy
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.15 {configuration option: "exportselection"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -exportselection no
    .t cget -exportselection
} -cleanup {
    destroy .t
} -result 0
test text-1.16 {configuration option: "exportselection"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -exportselection maybe
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.17 {configuration option: "fg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -fg red
    .t cget -fg
} -cleanup {
    destroy .t
} -result {red}
test text-1.18 {configuration option: "fg"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -fg stupid
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.19 {configuration option: "font"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -font fixed
    .t cget -font
} -cleanup {
    destroy .t
} -result {fixed}
test text-1.20 {configuration option: "font"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -font {}
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.21 {configuration option: "foreground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -foreground #012
    .t cget -foreground
} -cleanup {
    destroy .t
} -result {#012}
test text-1.22 {configuration option: "foreground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -foreground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.23 {configuration option: "height"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -height 5
    .t cget -height
} -cleanup {
    destroy .t
} -result 5
test text-1.24 {configuration option: "height"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -height bad
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.25 {configuration option: "highlightbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightbackground #123
    .t cget -highlightbackground
} -cleanup {
    destroy .t
} -result {#123}
test text-1.26 {configuration option: "highlightbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.27 {configuration option: "highlightcolor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightcolor #234
    .t cget -highlightcolor
} -cleanup {
    destroy .t
} -result {#234}
test text-1.28 {configuration option: "highlightcolor"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightcolor bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.29 {configuration option: "highlightthickness"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightthickness -2
    .t cget -highlightthickness
} -cleanup {
    destroy .t
} -result 0
test text-1.30 {configuration option: "highlightthickness"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -highlightthickness bad
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.31 {configuration option: "inactiveselectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -inactiveselectbackground #ffff01234567
    .t cget -inactiveselectbackground
} -cleanup {
    destroy .t
} -result {#ffff01234567}
test text-1.32 {configuration option: "inactiveselectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -inactiveselectbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.33 {configuration option: "insertbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertbackground green
    .t cget -insertbackground
} -cleanup {
    destroy .t
} -result {green}
test text-1.34 {configuration option: "insertbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertbackground <bogus>
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.35 {configuration option: "insertborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertborderwidth 45
    .t cget -insertborderwidth
} -cleanup {
    destroy .t
} -result 45
test text-1.36 {configuration option: "insertborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertborderwidth bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.37 {configuration option: "insertofftime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertofftime 100
    .t cget -insertofftime
} -cleanup {
    destroy .t
} -result 100
test text-1.38 {configuration option: "insertofftime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertofftime 2.4
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.39 {configuration option: "insertontime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertontime 47
    .t cget -insertontime
} -cleanup {
    destroy .t
} -result 47
test text-1.40 {configuration option: "insertontime"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertontime e1
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.41 {configuration option: "insertwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertwidth 2.3
    .t cget -insertwidth
} -cleanup {
    destroy .t
} -result 2
test text-1.42 {configuration option: "insertwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -insertwidth 47d
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.43 {configuration option: "maxundo"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -maxundo 5
    .t cget -maxundo
450
451
452
453
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
450
451
452
453
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







-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+


















-
+







    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -maxundo noway
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.45 {configuration option: "padx"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -padx 3.4
    .t cget -padx
} -cleanup {
    destroy .t
} -result 3
test text-1.46 {configuration option: "padx"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -padx 2.4.
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.47 {configuration option: "pady"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -pady 82
    .t cget -pady
} -cleanup {
    destroy .t
} -result 82
test text-1.48 {configuration option: "pady"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -pady bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.49 {configuration option: "relief"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -relief raised
    .t cget -relief
} -cleanup {
    destroy .t
} -result {raised}
test text-1.50 {configuration option: "relief"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -relief bumpy
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.51 {configuration option: "selectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectbackground #ffff01234567
    .t cget -selectbackground
} -cleanup {
    destroy .t
} -result {#ffff01234567}
test text-1.52 {configuration option: "selectbackground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectbackground bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.53 {configuration option: "selectborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectborderwidth 21
    .t cget -selectborderwidth
} -cleanup {
    destroy .t
} -result 21
test text-1.54 {configuration option: "selectborderwidth"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectborderwidth 3x
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.55 {configuration option: "selectforeground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectforeground yellow
    .t cget -selectforeground
} -cleanup {
    destroy .t
} -result {yellow}
test text-1.56 {configuration option: "selectforeground"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -selectforeground #12345
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.57 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 20
    .t cget -spacing1
} -cleanup {
    destroy .t
} -result 20
test text-1.58 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 1.3x
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.59 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 -5
    .t cget -spacing1
} -cleanup {
    destroy .t
} -result 0
test text-1.60 {configuration option: "spacing1"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing1 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.61 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 5
    .t cget -spacing2
} -cleanup {
    destroy .t
} -result 5
test text-1.62 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.63 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 -1
    .t cget -spacing2
} -cleanup {
    destroy .t
} -result 0
test text-1.64 {configuration option: "spacing2"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing2 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.65 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 20
    .t cget -spacing3
} -cleanup {
    destroy .t
} -result 20
test text-1.66 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.67 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 -10
    .t cget -spacing3
} -cleanup {
    destroy .t
} -result 0
test text-1.68 {configuration option: "spacing3"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -spacing3 bogus
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.69 {configuration option: "state"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -state d
    .t cget -state
} -cleanup {
    destroy .t
} -result {disabled}
test text-1.70 {configuration option: "state"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -state foo
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.71 {configuration option: "tabs"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabs {1i 2i 3i 4i}
    .t cget -tabs
} -cleanup {
    destroy .t
} -result {1i 2i 3i 4i}
test text-1.72 {configuration option: "tabs"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabs bad_tabs
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.73 {configuration option: "tabstyle"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabstyle wordprocessor
    .t cget -tabstyle
} -cleanup {
    destroy .t
} -result {wordprocessor}
test text-1.74 {configuration option: "tabstyle"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -tabstyle garbage
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.75 {configuration option: "undo"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -undo 1
    .t cget -undo
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
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







-
+


















-
+


















-
+







    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -undo eh
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.77 {configuration option: "width"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -width 73
    .t cget -width
} -cleanup {
    destroy .t
} -result 73
test text-1.78 {configuration option: "width"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -width 2.4
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.79 {configuration option: "wrap"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -wrap w
    .t cget -wrap
} -cleanup {
    destroy .t
} -result {word}
test text-1.80 {configuration option: "wrap"} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -wrap bad_wrap
} -cleanup {
    destroy .t
} -match glob -returnCodes {error} -result {*}
} -match glob -returnCodes error -result {*}
test text-1.81 {text options} -setup {
    text .t -borderwidth 2 -highlightthickness 2 -font {Courier -12 bold}
    pack .t
    update
} -body {
    .t configure -takefocus "any old thing"
    .t cget -takefocus
875
876
877
878
879
880
881
882

883
884
885

886
887
888
889
890

891
892
893
894
895
896
897
875
876
877
878
879
880
881

882
883
884

885
886
887
888
889

890
891
892
893
894
895
896
897







-
+


-
+




-
+







} -cleanup {
    destroy .t
} -result {bad insertunfocussed "gorp": must be hollow, none, or solid}


test text-2.1 {Tk_TextCmd procedure} -body {
    text
} -returnCodes {error} -result {wrong # args: should be "text pathName ?-option value ...?"}
} -returnCodes error -result {wrong # args: should be "text pathName ?-option value ...?"}
test text-2.2 {Tk_TextCmd procedure} -body {
    text foobar
} -returnCodes {error} -result {bad window path name "foobar"}
} -returnCodes error -result {bad window path name "foobar"}
test text-2.3 {Tk_TextCmd procedure} -body {
    text .t -gorp nofun
} -cleanup {
    destroy .t
} -returnCodes {error} -result {unknown option "-gorp"}
} -returnCodes error -result {unknown option "-gorp"}
test text-2.4 {Tk_TextCmd procedure} -body {
    catch {text .t -gorp nofun}
    winfo exists .t
} -cleanup {
    destroy .t
} -result 0
test text-2.5 {Tk_TextCmd procedure} -body {
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
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







-
+






-
+







-
+






-
+






-
+







-
+






-
+






-
+
















-
+






-
+






-
+






-
+








test text-3.1 {TextWidgetCmd procedure, basics} -setup {
    text .t
} -body {
    .t
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t option ?arg ...?"}
} -returnCodes error -result {wrong # args: should be ".t option ?arg ...?"}
test text-3.2 {TextWidgetCmd procedure} -setup {
    text .t
} -body {
    .t gorp 1.0 z 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "gorp": must be 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, or yview}
} -returnCodes error -result {bad option "gorp": must be 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, or yview}

test text-4.1 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t bbox index"}
} -returnCodes error -result {wrong # args: should be ".t bbox index"}
test text-4.2 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t bbox index"}
} -returnCodes error -result {wrong # args: should be ".t bbox index"}
test text-4.3 {TextWidgetCmd procedure, "bbox" option} -setup {
    text .t
} -body {
    .t bbox bad_mark
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "bad_mark"}
} -returnCodes error -result {bad text index "bad_mark"}

test text-5.1 {TextWidgetCmd procedure, "cget" option} -setup {
    text .t
} -body {
    .t cget
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t cget option"}
} -returnCodes error -result {wrong # args: should be ".t cget option"}
test text-5.2 {TextWidgetCmd procedure, "cget" option} -setup {
    text .t
} -body {
    .t cget a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t cget option"}
} -returnCodes error -result {wrong # args: should be ".t cget option"}
test text-5.3 {TextWidgetCmd procedure, "cget" option} -setup {
    text .t
} -body {
    .t cget -gorp
} -cleanup {
    destroy .t
} -returnCodes {error} -result {unknown option "-gorp"}
} -returnCodes error -result {unknown option "-gorp"}
test text-5.4 {TextWidgetCmd procedure, "cget" option} -setup {
    text .t
} -body {
    .t configure -bd 17
    .t cget -bd
} -cleanup {
    destroy .t
} -result 17


test text-6.1 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t compare a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t compare index1 op index2"}
} -returnCodes error -result {wrong # args: should be ".t compare index1 op index2"}
test text-6.2 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t compare a b c d
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t compare index1 op index2"}
} -returnCodes error -result {wrong # args: should be ".t compare index1 op index2"}
test text-6.3 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t compare @x == 1.0
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@x"}
} -returnCodes error -result {bad text index "@x"}
test text-6.4 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t compare 1.0 < @y
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@y"}
} -returnCodes error -result {bad text index "@y"}
test text-6.5 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
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
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







-
+













-
+













-
+













-
+








-
+






-
+







Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t compare 1.0 <x 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad comparison operator "<x": must be <, <=, ==, >=, >, or !=}
} -returnCodes error -result {bad comparison operator "<x": must be <, <=, ==, >=, >, or !=}
test text-6.12 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t compare 1.0 >> 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad comparison operator ">>": must be <, <=, ==, >=, >, or !=}
} -returnCodes error -result {bad comparison operator ">>": must be <, <=, ==, >=, >, or !=}
test text-6.13 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t compare 1.0 z 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad comparison operator "z": must be <, <=, ==, >=, >, or !=}
} -returnCodes error -result {bad comparison operator "z": must be <, <=, ==, >=, >, or !=}
test text-6.14 {TextWidgetCmd procedure, "compare" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
Line 7"
    .t co 1.0 z 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {ambiguous option "co": must be 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, or yview}
} -returnCodes error -result {ambiguous option "co": must be 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, or yview}
# "configure" option is already covered above

test text-7.1 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug 0 1
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t debug boolean"}
} -returnCodes error -result {wrong # args: should be ".t debug boolean"}
test text-7.2 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t de 0 1
} -cleanup {
    destroy .t
} -returnCodes {error} -result {ambiguous option "de": must be 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, or yview}
} -returnCodes error -result {ambiguous option "de": must be 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, or yview}
test text-7.3 {TextWidgetCmd procedure, "debug" option} -setup {
    text .t
} -body {
    .t debug true
    .t deb
} -cleanup {
    destroy .t
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
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







-
+






-
+






-
+









-
+








test text-8.1 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t delete
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t delete index1 ?index2 ...?"}
} -returnCodes error -result {wrong # args: should be ".t delete index1 ?index2 ...?"}
test text-8.2 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t delete a b c
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "a"}
} -returnCodes error -result {bad text index "a"}
test text-8.3 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t delete @x 2.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@x"}
} -returnCodes error -result {bad text index "@x"}
test text-8.4 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345"
    .t delete 2.3 @y
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@y"}
} -returnCodes error -result {bad text index "@y"}
test text-8.5 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
1292
1293
1294
1295
1296
1297
1298
1299

1300
1301
1302
1303
1304
1305
1306
1292
1293
1294
1295
1296
1297
1298

1299
1300
1301
1302
1303
1304
1305
1306







-
+







    .t insert 1.0 "Line 1
abcdefghijklm
12345"
    # All indices are checked before we actually delete anything
    .t delete 2.1 2.3 foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "foo"}
} -returnCodes error -result {bad text index "foo"}
test text-8.9 {TextWidgetCmd procedure, "delete" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345"
# All indices are checked before we actually delete anything
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
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







-
+









-
+







} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345"
    .t replace 1.3 2.3
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t replace index1 index2 chars ?tagList chars tagList ...?"}
} -returnCodes error -result {wrong # args: should be ".t replace index1 index2 chars ?tagList chars tagList ...?"}
test text-8.19 {TextWidgetCmd procedure, "replace" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345"
    .t replace 3.1 2.3 foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {index "2.3" before "3.1" in the text}
} -returnCodes error -result {index "2.3" before "3.1" in the text}
test text-8.20 {TextWidgetCmd procedure, "replace" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
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
1481
1482
1483
1484
1485
1486
1487

1488












1489
1490
1491
1492
1493
1494
1495







-
+
-
-
-
-
-
-
-
-
-
-
-
-







    proc .t {args} { lappend ::res $args ; uplevel 1 test.t $args }
    .t edit undo
    return $res
} -cleanup {
    rename .t {}
    rename test.t .t
    destroy .t
} -result [list {edit undo} {delete 2.1 2.4} {mark set insert 2.1} {see insert} \
} -result {{edit undo} {delete 2.1 2.4} {mark set insert 2.1} {see insert} {insert 2.1 ef} {mark set insert 2.3} {see insert}}
                {mark set tk::undoMarkL2 2.1} {mark set tk::undoMarkR2 2.4} \
                {mark gravity tk::undoMarkL2 left} {mark gravity tk::undoMarkR2 right} \
                {insert 2.1 ef} {mark set insert 2.3} {see insert} \
                {mark set tk::undoMarkL1 2.1} {mark set tk::undoMarkR1 2.3} \
                {mark gravity tk::undoMarkL1 left} {mark gravity tk::undoMarkR1 right} \
                {mark names} \
                {index tk::undoMarkL1} {index tk::undoMarkR1} \
                {mark unset tk::undoMarkL1 tk::undoMarkR1} \
                {index tk::undoMarkL2} {index tk::undoMarkR2} \
                {mark unset tk::undoMarkL2 tk::undoMarkR2} \
                {compare 2.1 > 2.3} {compare 2.6 > 2.3} ]

test text-8.23 {TextWidgetCmd procedure, "replace" option with undo} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
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
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







-
+






-
+






-
+






-
+








test text-9.1 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t get ?-displaychars? ?--? index1 ?index2 ...?"}
} -returnCodes error -result {wrong # args: should be ".t get ?-displaychars? ?--? index1 ?index2 ...?"}
test text-9.2 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get a b c
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "a"}
} -returnCodes error -result {bad text index "a"}
test text-9.3 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get @q 3.1
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@q"}
} -returnCodes error -result {bad text index "@q"}
test text-9.4 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get 3.1 @r
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@r"}
} -returnCodes error -result {bad text index "@r"}
test text-9.5 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
1863
1864
1865
1866
1867
1868
1869
1870

1871
1872
1873
1874
1875
1876
1877
1851
1852
1853
1854
1855
1856
1857

1858
1859
1860
1861
1862
1863
1864
1865







-
+







!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 5.2 5.4
    .t get 5.2 5.4 5.5 foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "foo"}
} -returnCodes error -result {bad text index "foo"}
test text-9.21 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
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
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







-
+






-
+






-
+






-
+






-
+








test text-10.1 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t count
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t count ?-option value ...? index1 index2"}
} -returnCodes error -result {wrong # args: should be ".t count ?-option value ...? index1 index2"}
test text-10.2 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t count blah 1.0 2.0
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "blah": must be -chars, -displaychars, -displayindices, -displaylines, -indices, -lines, -update, -xpixels, or -ypixels}
} -returnCodes error -result {bad option "blah" must be -chars, -displaychars, -displayindices, -displaylines, -indices, -lines, -update, -xpixels, or -ypixels}
test text-10.3 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t count a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "a"}
} -returnCodes error -result {bad text index "a"}
test text-10.4 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t count @q 3.1
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@q"}
} -returnCodes error -result {bad text index "@q"}
test text-10.5 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t count 3.1 @r
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@r"}
} -returnCodes error -result {bad text index "@r"}
test text-10.6 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
2183
2184
2185
2186
2187
2188
2189
2190

2191
2192
2193
2194
2195
2196
2197
2171
2172
2173
2174
2175
2176
2177

2178
2179
2180
2181
2182
2183
2184
2185







-
+







bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t count 5.2 foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "foo"}
} -returnCodes error -result {bad text index "foo"}
test text-10.13 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
2248
2249
2250
2251
2252
2253
2254
2255

2256
2257
2258
2259
2260
2261
2262
2236
2237
2238
2239
2240
2241
2242

2243
2244
2245
2246
2247
2248
2249
2250







-
+







!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.0 3.0
} -cleanup {
    destroy .t
} -result 3
2271
2272
2273
2274
2275
2276
2277
2278

2279
2280
2281
2282
2283
2284
2285
2259
2260
2261
2262
2263
2264
2265

2266
2267
2268
2269
2270
2271
2272
2273







-
+







!@#$%
Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.2 3.0
} -cleanup {
    destroy .t
} -result 1
2296
2297
2298
2299
2300
2301
2302
2303

2304
2305
2306
2307
2308
2309
2310
2284
2285
2286
2287
2288
2289
2290

2291
2292
2293
2294
2295
2296
2297
2298







-
+







    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
    .t mark set a 2.2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices a 3.0
} -cleanup {
    destroy .t
} -result 0
2320
2321
2322
2323
2324
2325
2326
2327

2328
2329
2330
2331
2332
2333
2334
2308
2309
2310
2311
2312
2313
2314

2315
2316
2317
2318
2319
2320
2321
2322







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displayindices 2.0 4.2
} -cleanup {
    destroy .t
} -result 6
2344
2345
2346
2347
2348
2349
2350
2351

2352
2353
2354
2355
2356
2357
2358
2332
2333
2334
2335
2336
2337
2338

2339
2340
2341
2342
2343
2344
2345
2346







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 3.0
} -cleanup {
    destroy .t
} -result 2
2368
2369
2370
2371
2372
2373
2374
2375

2376
2377
2378
2379
2380
2381
2382
2356
2357
2358
2359
2360
2361
2362

2363
2364
2365
2366
2367
2368
2369
2370







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.2 3.0
} -cleanup {
    destroy .t
} -result 1
2393
2394
2395
2396
2397
2398
2399
2400

2401
2402
2403
2404
2405
2406
2407
2381
2382
2383
2384
2385
2386
2387

2388
2389
2390
2391
2392
2393
2394
2395







-
+







    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars a 3.0
} -cleanup {
    destroy .t
} -result 0
2417
2418
2419
2420
2421
2422
2423
2424

2425
2426
2427
2428
2429
2430
2431
2405
2406
2407
2408
2409
2410
2411

2412
2413
2414
2415
2416
2417
2418
2419







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
} -cleanup {
    destroy .t
} -result 5
2441
2442
2443
2444
2445
2446
2447
2448

2449
2450
2451
2452
2453
2454
2455
2429
2430
2431
2432
2433
2434
2435

2436
2437
2438
2439
2440
2441
2442
2443







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    list [.t count -indices 2.2 3.0] [.t count 2.2 3.0]
} -cleanup {
    destroy .t
2467
2468
2469
2470
2471
2472
2473
2474

2475
2476
2477
2478
2479
2480
2481
2455
2456
2457
2458
2459
2460
2461

2462
2463
2464
2465
2466
2467
2468
2469







-
+







    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    list [.t count -indices a 3.0] [.t count a 3.0]
} -cleanup {
    destroy .t
} -result {9 9}
2491
2492
2493
2494
2495
2496
2497
2498

2499
2500
2501
2502
2503
2504
2505
2479
2480
2481
2482
2483
2484
2485

2486
2487
2488
2489
2490
2491
2492
2493







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -indices 2.0 4.2
} -cleanup {
    destroy .t
2516
2517
2518
2519
2520
2521
2522
2523

2524
2525
2526
2527
2528
2529
2530
2504
2505
2506
2507
2508
2509
2510

2511
2512
2513
2514
2515
2516
2517
2518







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -chars 2.2 3.0
} -cleanup {
    destroy .t
2542
2543
2544
2545
2546
2547
2548
2549

2550
2551
2552
2553
2554
2555
2556
2530
2531
2532
2533
2534
2535
2536

2537
2538
2539
2540
2541
2542
2543
2544







-
+







    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
    .t mark set a 2.2
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3, but 'a' is automatically moved to 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -chars a 3.0
} -cleanup {
    destroy .t
} -result 9
2566
2567
2568
2569
2570
2571
2572
2573

2574
2575
2576
2577
2578
2579
2580
2554
2555
2556
2557
2558
2559
2560

2561
2562
2563
2564
2565
2566
2567
2568







-
+







Line 7"
    .t tag configure elide -elide 1
    .t tag add elide 2.2 3.4
    .t tag add elide 4.0 4.1
# Create one visible and one invisible window
    frame .t.w1
    frame .t.w2
# Creating this window here means that the elidden text
# Creating this window here means that the elided text
# now starts at 2.3
    .t window create 2.1 -window .t.w1
    .t window create 3.1 -window .t.w2
    .t count -displaychars 2.0 4.2
    .t count -chars 2.0 4.2
} -cleanup {
    destroy .t
2604
2605
2606
2607
2608
2609
2610
2611

2612
2613
2614
2615
2616
2617
2618
2592
2593
2594
2595
2596
2597
2598

2599
2600
2601
2602
2603
2604
2605
2606







-
+







} -body {
    .t insert end [string repeat "abcde " 50]\n
    .t insert end [string repeat "fghij " 50]\n
    .t insert end [string repeat "klmno " 50]
    .t count -lines 1.0 2.0 3.0
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "1.0": must be -chars, -displaychars, -displayindices, -displaylines, -indices, -lines, -update, -xpixels, or -ypixels}
} -returnCodes error -result {bad option "1.0" must be -chars, -displaychars, -displayindices, -displaylines, -indices, -lines, -update, -xpixels, or -ypixels}
test text-10.33 {TextWidgetCmd procedure, "count" option} -setup {
    text .t
} -body {
    .t insert end [string repeat "abcde " 50]\n
    .t insert end [string repeat "fghij " 50]\n
    .t insert end [string repeat "klmno " 50]
    .t count -lines end end
3118
3119
3120
3121
3122
3123
3124
3125

3126
3127
3128
3129
3130
3131
3132
3106
3107
3108
3109
3110
3111
3112

3113
3114
3115
3116
3117
3118
3119
3120







-
+







    # At this time the line metrics should be up-to-date (pendingsync is 0).
    lappend res "Pending:[.top.yt pendingsync]"
    set res
} -cleanup {
    destroy .top.yt .top
} -result {Sync:0 Pending:1 Sync:1 Pending:0}

test text-11a.51 {<<WidgetViewSync>> calls Tk_SendVirtualEvent(),
test text-11a.51 {<<WidgetViewSync>> calls TkSendVirtualEvent(),
                  NOT Tk_HandleEvent().
                  Bug [b362182e45704dd7bbd6aed91e48122035ea3d16]} -setup {
    destroy .top.t .top
} -body {
    set res {}
    toplevel .top
    pack [text .top.t]
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
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







-
+






-
+






-
+






-
+








test text-12.1 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t index
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t index index"}
} -returnCodes error -result {wrong # args: should be ".t index index"}
test text-12.2 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t ind a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t index index"}
} -returnCodes error -result {wrong # args: should be ".t index index"}
test text-12.3 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t in a b
} -cleanup {
    destroy .t
} -returnCodes {error} -result {ambiguous option "in": must be 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, or yview}
} -returnCodes error -result {ambiguous option "in": must be 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, or yview}
test text-12.4 {TextWidgetCmd procedure, "index" option} -setup {
    text .t
} -body {
    .t index @xyz
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "@xyz"}
} -returnCodes error -result {bad text index "@xyz"}
test text-12.5 {TextWidgetCmd procedure, "index" option} -setup {
    [text .t] insert 1.0 "Line 1
aefghijklm
12345
Line 4
bOy GIrl .#@? x_yz
!@#$%
3193
3194
3195
3196
3197
3198
3199
3200

3201
3202
3203
3204
3205
3206
3207
3181
3182
3183
3184
3185
3186
3187

3188
3189
3190
3191
3192
3193
3194
3195







-
+







bOy GIrl .#@? x_yz
!@#$%
Line 7"
} -body {
    .t insert 1.2
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t insert index chars ?tagList chars tagList ...?"}
} -returnCodes error -result {wrong # args: should be ".t insert index chars ?tagList chars tagList ...?"}
test text-13.2 {TextWidgetCmd procedure, "insert" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Line 1
aefghijklm
12345
Line 4
3273
3274
3275
3276
3277
3278
3279
3280

3281
3282
3283
3284
3285
3286
3287
3261
3262
3263
3264
3265
3266
3267

3268
3269
3270
3271
3272
3273
3274
3275







-
+







} -result {{1.3 1.4} {1.3 1.4} {1.0 1.3 1.4 1.12} {1.0 1.3 1.4 1.12} {1.0 1.12}}
test text-13.8 {TextWidgetCmd procedure, "insert" option} -setup {
    text .t
} -body {
    .t insert 1.0 "Sample text" "a \{b"
} -cleanup {
    destroy .t
} -returnCodes {error} -result {unmatched open brace in list}
} -returnCodes error -result {unmatched open brace in list}
test text-13.9 {TextWidgetCmd procedure, "insert" option} -setup {
    text .t
} -body {
    .t insert 1.0 "First" bold " " {} second "x y z" " third"
    list [.t get 1.0 1.end] [.t tag ranges bold] [.t tag ranges x] \
	    [.t tag ranges y] [.t tag ranges z]
} -cleanup {
3300
3301
3302
3303
3304
3305
3306
3307

3308
3309
3310
3311
3312
3313
3314
3288
3289
3290
3291
3292
3293
3294

3295
3296
3297
3298
3299
3300
3301
3302







-
+








test text-14.1 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -state foobar
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad state "foobar": must be disabled or normal}
} -returnCodes error -result {bad state "foobar": must be disabled or normal}
test text-14.2 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -spacing1 -2 -spacing2 1 -spacing3 1
    list [.t cget -spacing1] [.t cget -spacing2] [.t cget -spacing3]
} -cleanup {
    destroy .t
3331
3332
3333
3334
3335
3336
3337
3338

3339
3340
3341
3342
3343
3344
3345
3319
3320
3321
3322
3323
3324
3325

3326
3327
3328
3329
3330
3331
3332
3333







-
+







} -result {1 1 0}
test text-14.5 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -tabs {30 foo}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad tab alignment "foo": must be left, right, center, or numeric}
} -returnCodes error -result {bad tab alignment "foo": must be left, right, center, or numeric}
test text-14.6 {ConfigureText procedure} -setup {
    text .t
} -body {
    catch {.t configure -tabs {30 foo}}
    .t configure -tabs {10 20 30}
    return $errorInfo
} -cleanup {
3359
3360
3361
3362
3363
3364
3365
3366

3367
3368
3369
3370
3371
3372
3373
3347
3348
3349
3350
3351
3352
3353

3354
3355
3356
3357
3358
3359
3360
3361







-
+







} -result {}
test text-14.8 {ConfigureText procedure} -setup {
   text .t
} -body {
    .t configure -wrap bogus
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad wrap "bogus": must be char, none, or word}
} -returnCodes error -result {bad wrap "bogus": must be char, none, or word}
test text-14.9 {ConfigureText procedure} -setup {
    text .t -font {Courier -12} -borderwidth 2 -highlightthickness 2
} -body {
    .t configure -selectborderwidth 17 -selectforeground #332211 \
	    -selectbackground #abc
    list [lindex [.t tag config sel -borderwidth] 4] \
	   [lindex [.t tag config sel -foreground] 4] \
3385
3386
3387
3388
3389
3390
3391
3392

3393
3394
3395
3396
3397
3398
3399
3373
3374
3375
3376
3377
3378
3379

3380
3381
3382
3383
3384
3385
3386
3387







-
+







} -result {}
test text-14.11 {ConfigureText procedure} -setup {
    text .t
} -body {
    .t configure -selectborderwidth foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad screen distance "foo"}
} -returnCodes error -result {bad screen distance "foo"}
test text-14.12 {ConfigureText procedure} -body {
    text .t
    entry .t.e
    .t.e insert end abcdefg
    .t.e select from 0
    .t.e select to 2
    text .t2 -exportselection 1
3483
3484
3485
3486
3487
3488
3489
3490

3491
3492
3493
3494
3495
3496
3497
3471
3472
3473
3474
3475
3476
3477

3478
3479
3480
3481
3482
3483
3484
3485







-
+







    destroy .top
} -result {150x140+}
# This test was failing Windows because the title bar on .t was a certain
# minimum size and it was interfering with the size requested by the -setgrid.
# The "overrideredirect" gets rid of the titlebar so the toplevel can shrink
# to the appropriate size.
# On macOS, however, there is no way to make the window overlap the menubar.
if {[tk windowingsystem] == "aqua"} {
if {[tk windowingsystem] eq "aqua"} {
    set minY [expr [menubarheight] + 1]
} else {
    set minY 0
}
test text-14.19 {ConfigureText procedure} -setup {
    toplevel .top
    text .top.t -font {Courier -12} -borderwidth 2 -highlightthickness 2
3687
3688
3689
3690
3691
3692
3693
3694

3695
3696
3697
3698
3699
3700

3701
3702
3703
3704
3705
3706
3707
3675
3676
3677
3678
3679
3680
3681

3682
3683
3684
3685
3686
3687

3688
3689
3690
3691
3692
3693
3694
3695







-
+





-
+







} -result {
}
test text-19.2 {DeleteChars procedure} -body {
    text .t
    .t delete foobar
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "foobar"}
} -returnCodes error -result {bad text index "foobar"}
test text-19.3 {DeleteChars procedure} -body {
    text .t
    .t delete 1.0 lousy
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "lousy"}
} -returnCodes error -result {bad text index "lousy"}
test text-19.4 {DeleteChars procedure} -body {
    text .t
    .t insert 1.0 "Line 1
abcde
12345
Line 4"
    .t delete 2.1
4080
4081
4082
4083
4084
4085
4086
4087

4088
4089
4090
4091
4092
4093
4094
4068
4069
4070
4071
4072
4073
4074

4075
4076
4077
4078
4079
4080
4081
4082







-
+







} -result {1.9 2}
test text-22.8 {TextSearchCmd procedure, -count option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -count
} -cleanup {
    destroy .t
} -returnCodes {error} -result {no value given for "-count" option}
} -returnCodes error -result {no value given for "-count" option}
test text-22.9 {TextSearchCmd procedure, -nocase option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    list [.t search -nocase BaR 1.1] [.t search BaR 1.1]
} -cleanup {
    destroy .t
} -result {2.13 2.23}
4108
4109
4110
4111
4112
4113
4114
4115

4116
4117
4118
4119
4120
4121
4122
4096
4097
4098
4099
4100
4101
4102

4103
4104
4105
4106
4107
4108
4109
4110







-
+







} -result {2.13}
test text-22.12 {TextSearchCmd procedure, -nolinestop option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -nolinestop BaR 1.1
} -cleanup {
    destroy .t
} -returnCodes {error} -result {the "-nolinestop" option requires the "-regexp" option to be present}
} -returnCodes error -result {the "-nolinestop" option requires the "-regexp" option to be present}
test text-22.13 {TextSearchCmd procedure, -nolinestop option} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    set msg ""
    list [.t search -nolinestop -regexp -count msg e.*o 1.1] $msg
} -cleanup {
    destroy .t
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
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







-
+






-
+





-
+




















-
+













-
+







} -result {2.4}
test text-22.15 {TextSearchCmd procedure, argument parsing} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search abc
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t search ?switches? pattern index ?stopIndex?"}
} -returnCodes error -result {wrong # args: should be ".t search ?switches? pattern index ?stopIndex?"}
test text-22.16 {TextSearchCmd procedure, argument parsing} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search abc d e f
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t search ?switches? pattern index ?stopIndex?"}
} -returnCodes error -result {wrong # args: should be ".t search ?switches? pattern index ?stopIndex?"}
test text-22.17 {TextSearchCmd procedure, check index} -body {
    text .t
    .t search abc gorp
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "gorp"}
} -returnCodes error -result {bad text index "gorp"}
test text-22.18 {TextSearchCmd procedure, startIndex == "end"} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search non-existent end
} -cleanup {
    destroy .t
} -result {}
test text-22.19 {TextSearchCmd procedure, startIndex == "end"} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search non-existent end
} -cleanup {
    destroy .t
} -result {}
test text-22.20 {TextSearchCmd procedure, bad stopIndex} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search abc 1.0 lousy
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "lousy"}
} -returnCodes error -result {bad text index "lousy"}
test text-22.21 {TextSearchCmd procedure, pattern case conversion} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    list [.t search -nocase BAR 1.1] [.t search BAR 1.1]
} -cleanup {
    destroy .t
} -result {2.13 {}}
test text-22.22 {TextSearchCmd procedure, bad regular expression pattern} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -regexp a( 1.0
} -cleanup {
    destroy .t
} -returnCodes {error} -result {couldn't compile regular expression pattern: parentheses () not balanced}
} -returnCodes error -match glob -result {*t compile regular expression pattern: parentheses () not balanced}
test text-22.23 {TextSearchCmd procedure, skip dummy last line} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -backwards BaR end 1.0
} -cleanup {
    destroy .t
} -result {2.23}
4482
4483
4484
4485
4486
4487
4488
4489

4490
4491
4492
4493
4494
4495
4496
4470
4471
4472
4473
4474
4475
4476

4477
4478
4479
4480
4481
4482
4483
4484







-
+







test text-22.56 {TextSearchCmd procedure, error setting variable} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    set a 44
    .t search -count a(2) xyz 1.0
} -cleanup {
    destroy .t
} -returnCodes {error} -result {can't set "a(2)": variable isn't array}
} -returnCodes error -match glob -result {can*t set "a(2)": variable is* array}
test text-22.57 {TextSearchCmd procedure, wrap-around} -body {
    text .t
    .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx"
    .t search -backwards xyz 1.1
} -cleanup {
    destroy .t
} -result {3.5}
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
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







-
-
+
+





-
-
+
+






-
+

-
-
+
+







    set p $p$p$p$p$p
    .t search -nocase $p 1.0
} -cleanup {
    destroy .t
} -result {}
test text-22.69 {TextSearchCmd, unicode} -body {
    text .t
    .t insert end "fooドナbar"
    .t search ドナ 1.0
    .t insert end "foo\u30c9\u30cabar"
    .t search \u30c9\u30ca 1.0
} -cleanup {
    destroy .t
} -result {1.3}
test text-22.70 {TextSearchCmd, unicode} -body {
    text .t
    .t insert end "fooドナbar"
    list [.t search -count n ドナ 1.0] $n
    .t insert end "foo\u30c9\u30cabar"
    list [.t search -count n \u30c9\u30ca 1.0] $n
} -cleanup {
    destroy .t
} -result {1.3 2}
test text-22.71 {TextSearchCmd, unicode with non-text segments} -body {
    text .t
    button .b1 -text baz
    .t insert end "foo"
    .t insert end "foo\u30c9"
    .t window create end -window .b1
    .t insert end "bar"
    list [.t search -count n ドナ 1.0] $n
    .t insert end "\u30cabar"
    list [.t search -count n \u30c9\u30ca 1.0] $n
} -cleanup {
    destroy .t .b1
} -result {1.3 3}
test text-22.72 {TextSearchCmd, hidden text does not affect match index} -body {
    pack [text .t]
    .t insert end "12345H7890"
    .t search 7 1.0
5820
5821
5822
5823
5824
5825
5826
5827

5828
5829
5830
5831
5832
5833
5834
5808
5809
5810
5811
5812
5813
5814

5815
5816
5817
5818
5819
5820
5821
5822







-
+







} -result {{} {} 1.0 2.1 2.0 3.1 2.0 3.0}
test text-22.217.1 {elide up to match, with UTF-8 chars before the match} -setup {
    pack [text .t]
    set res {}
} -body {
    .t tag configure e -elide 0
    .t insert end A {} xyz e bb\n
    .t insert end Ä {} xyz e bb
    .t insert end \u00c4 {} xyz e bb
    set res {}
    lappend res [.t search bb 1.0 "1.0 lineend"]
    lappend res [.t search bb 2.0 "2.0 lineend"]
    lappend res [.t search -regexp bb 1.0 "1.0 lineend"]
    lappend res [.t search -regexp bb 2.0 "2.0 lineend"]
    .t tag configure e -elide 1
    lappend res [.t search bb 1.0 "1.0 lineend"]
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
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







-
+






-
+

-
+






-
+

-
+










-
+













-
+













-
+






-
+

-
+






-
+









-
+







-
+







-
+







-
+







-
+







    lappend res [.t search -backwards a end]       ; # works
    lappend res [.t search -backwards -all a end]  ; # used to hang
} -cleanup {
    destroy .t
} -result {1.1 1.0 1.0}

test text-23.1 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs "\{{}"
} -cleanup {
    destroy .t
} -returnCodes {error} -result {unmatched open brace in list}
} -returnCodes error -result {unmatched open brace in list}
test text-23.2 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs xyz
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad screen distance "xyz"}
} -returnCodes error -result {bad screen distance "xyz"}
test text-23.3 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 200}
    update idletasks
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0]
} -cleanup {
    destroy .t
} -result {100 200}
test text-23.4 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 right 200 left 300 center 400 numeric}
    update idletasks
    list [expr {[lindex [.t bbox 1.2] 0] + [lindex [.t bbox 1.2] 2]}] \
	    [lindex [.t bbox 1.4] 0] \
	    [expr {[lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]/2}] \
	    [lindex [.t bbox 1.10] 0]
} -cleanup {
    destroy .t
} -result {100 200 300 400}
test text-23.5 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {105 r 205 l 305 c 405 n}
    update idletasks
    list [expr {[lindex [.t bbox 1.2] 0] + [lindex [.t bbox 1.2] 2]}] \
	    [lindex [.t bbox 1.4] 0] \
	    [expr {[lindex [.t bbox 1.6] 0] + [lindex [.t bbox 1.6] 2]/2}] \
	    [lindex [.t bbox 1.10] 0]
} -cleanup {
    destroy .t
} -result {105 205 305 405}
test text-23.6 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 left 200 lork}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad tab alignment "lork": must be left, right, center, or numeric}
} -returnCodes error -result {bad tab alignment "lork": must be left, right, center, or numeric}
test text-23.7 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 150
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs {100 !44 200 lork}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad screen distance "!44"}
} -returnCodes error -result {bad screen distance "!44"}


test text-24.1 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
} -returnCodes error -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
test text-24.2 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -all
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
} -returnCodes error -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
test text-24.3 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -command
} -cleanup {
    destroy .t
} -returnCodes {error} -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
} -returnCodes error -result {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}
test text-24.4 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump -bogus
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad option "-bogus": must be -all, -command, -image, -mark, -tag, -text, or -window}
} -returnCodes error -result {bad option "-bogus": must be -all, -command, -image, -mark, -tag, -text, or -window}
test text-24.5 {TextDumpCmd procedure, bad args} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t mark set insert 1.0
    .t dump bogus
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad text index "bogus"}
} -returnCodes error -result {bad text index "bogus"}
test text-24.6 {TextDumpCmd procedure, one index} -body {
    pack [text .t]
    .t insert 1.0 "One Line"
    .t dump -text 1.2
} -cleanup {
    destroy .t
} -result {text e 1.2}
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
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







-
+



-
+



-
+



-
+







    return $x
} -cleanup {
    destroy .t
    rename Append {}
} -result {mark 1.0 current mark 1.0 insert mark 2.4 m}
test text-24.25 {TextDumpCmd procedure, unicode characters} -body {
    text .t
    .t insert 1.0 ±±±
    .t insert 1.0 \xb1\xb1\xb1
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text ±±± 1.0 mark insert 1.3 mark current 1.3 text {\n} 1.3"
} -result "text \xb1\xb1\xb1 1.0 mark insert 1.3 mark current 1.3 text {\n} 1.3"
test text-24.26 {TextDumpCmd procedure, unicode characters} -body {
    text .t
    .t delete 1.0 end
    .t insert 1.0 abc±±±
    .t insert 1.0 abc\xb1\xb1\xb1
    .t dump -all 1.0 2.0
} -cleanup {
    destroy .t
} -result "text abc±±± 1.0 mark insert 1.6 mark current 1.6 text {\n} 1.6"
} -result "text abc\xb1\xb1\xb1 1.0 mark insert 1.6 mark current 1.6 text {\n} 1.6"
test text-24.27 {TextDumpCmd procedure, peer present} -body {
    text .t
    .t peer create .t.t
    .t dump -all 1.0 end
} -cleanup {
    destroy .t
} -result "mark insert 1.0 mark current 1.0 text {\n} 1.0"
6477
6478
6479
6480
6481
6482
6483
6484

6485
6486
6487
6488
6489
6490

6491
6492
6493
6494
6495
6496
6497
6465
6466
6467
6468
6469
6470
6471

6472
6473
6474
6475
6476
6477

6478
6479
6480
6481
6482
6483
6484
6485







-
+





-
+









test text-27.1 {TextEditCmd procedure, argument parsing} -body {
    pack [text .t]
    .t edit
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t edit option ?arg ...?"}
} -returnCodes error -result {wrong # args: should be ".t edit option ?arg ...?"}
test text-27.2 {TextEditCmd procedure, argument parsing} -body {
    pack [text .t]
    .t edit gorp
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad edit option "gorp": must be canundo, canredo, modified, redo, reset, separator, or undo}
} -returnCodes error -result {bad edit option "gorp": must be canundo, canredo, modified, redo, reset, separator, or undo}
test text-27.3 {TextEditUndo procedure, undoing changes} -body {
    text .t -undo 1
    pack .t
    .t insert end "line 1\n"
    .t delete 1.4 1.6
    .t insert end "should be gone after undo\n"
    .t edit undo
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6560
6561
6562
6563
6564
6565
6566

6567
6568
6569
6570
6571
6572
6573







-







} -result 1
test text-27.11 {TextEditCmd procedure, set modified flag repeat} -setup {
    text .t
    pack .t
# Make sure the Text is mapped before we start
    update
    set ::retval {}
    update
} -body {
    bind .t <<Modified>> "lappend ::retval modified"
# Shouldn't require [update idle] to trigger event [Bug 1809538]
    lappend ::retval [.t edit modified]
    .t edit modified 1
    update
    lappend ::retval [.t edit modified]
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
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







-
+













-
+







    .t insert end "There is a selection in this text widget,\n"
    .t insert end "and it will be impacted by the <<PasteSelection>> event received.\n"
    .t insert end "Therefore a <<Selection>> event must fire back."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y 3
    event generate .t <<PasteSelection>> -x 15 -y [lindex [.t dlineinfo 1.0] 1]
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {<<Selection>>_fired}
test text-27.15c {No <<Selection>> virtual event on <<PasteSelection>> outside widget selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "but it will not be impacted by the <<PasteSelection>> event received."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y 80
    event generate .t <<PasteSelection>> -x 15 -y [lindex [.t dlineinfo 2.0] 1]
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {no_<<Selection>>_event_fired}
test text-27.15d {<<Selection>> virtual event on <Delete> with cursor inside selection} -body {
    pack [text .t]
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
7060
7061
7062
7063
7064

7065
7066
7067
7068
7069
7070
7071
7072
7073
7074

7075
7076
7077
7078
7079
7080
7081
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







-
+

-

-
+
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
+
-


-
+
-














-
+





-
+









-
+







    .t edit undo
    update ; lappend res $nbUS
    .t edit reset
    update ; lappend res $nbUS
} -cleanup {
    destroy .t
} -result {0 0 1 2 3 4 4 5 6 6 7 8 8 9}
test text-27.26 {edit undo and edit redo return ranges} -setup {
test text-27.26 {bug ab839efc5f - .text edit undo inserts separators} -setup {
    destroy .t
    set res {}
} -body {
    text .t -undo true -autoseparators false
    text .t -undo 1
    .t insert end "Hello "
    .t edit separator
    .t insert end "World!\n"
    .t insert 1.6 "GREAT "
    .t insert 1.0 "1. 123 5 789012  LINE-1\n2.\n3. 123 5 789012  LINE-3\n"
    .t insert end "Another edit here!!"
    lappend res [.t edit undo]
    lappend res [.t edit redo]
    .t edit separator
    .t delete 1.6
    .t delete 1.9 1.10
    .t tag add sel 3.0 3.end
    .t delete sel.first sel.last
    .t edit undo
    .t tag add sel 3.0 3.end
    .t delete sel.first sel.last
    .t insert 1.9 L
    lappend res [.t edit undo]
    lappend res [.t edit redo]
    .t replace 1.6 1.10 Tcl/Tk
    .t replace 2.8 2.12 "one bites the dust"
    lappend res [.t edit undo]
    lappend res [.t edit redo]
} -cleanup {
    destroy .t
} -result [list {1.6 2.0}           \
                {1.6 2.19}          \
                {1.6 1.7 1.10 1.12} \
                {1.6 1.7 1.9 1.11}  \
                {1.6 1.16 2.8 2.19} \
                {1.6 1.16 2.8 2.30} ]
test text-27.27 {edit undo and edit redo return ranges} -setup {
    destroy .t
    set res {}
} -body {
    text .t -undo true -autoseparators false
    for {set i 3} {$i >= 1} {incr i -1} {
        .t insert 1.0 "Line $i\n"
    }
    lappend res [.t edit undo]
    lappend res [.t edit redo]
} -cleanup {
    destroy .t
} -result [list {1.0 2.0} \
                {1.0 4.0} ]
test text-27.28 {edit undo and edit redo do not leave \
                 spurious temporary marks behind them} -setup {
    destroy .t
    set res {}
} -body {
    pack [text .t -undo true -autoseparators false]
    .t insert end "Hello World.\n"
    .t edit separator
    .t insert end "Again hello.\n"
    .t edit undo
    lappend res [expr {[lsearch [.t mark names] tk::undoMark*]<0}]
    .t edit redo
    .t get 3.0 3.end
    lappend res [expr {[lsearch [.t mark names] tk::undoMark*]<0}]
} -cleanup {
    destroy .t
} -result {1 1}
} -result {3. 123 5 789012  LINE-3}


test text-28.1 {bug fix - 624372, ControlUtfProc long lines} -body {
    pack [text .t -wrap none]
    .t insert end [string repeat "\1" 500]
} -cleanup {
    destroy .t
} -result {}


test text-29.1 {tabs - must be positive and must be increasing} -body {
    pack [text .t -wrap none]
    .t configure -tabs 0
} -cleanup {
    destroy .t
} -returnCodes {error} -result {tab stop "0" is not at a positive distance}
} -returnCodes error -result {tab stop "0" is not at a positive distance}
test text-29.2 {tabs - must be positive and must be increasing} -body {
    pack [text .t -wrap none]
    .t configure -tabs -5
} -cleanup {
    destroy .t
} -returnCodes {error} -result {tab stop "-5" is not at a positive distance}
} -returnCodes error -result {tab stop "-5" is not at a positive distance}
test text-29.3 {tabs - must be positive and must be increasing} -constraints {
    knownBug
} -body {
# This bug will be fixed in Tk 9.0, when we can allow a minor
# incompatibility with Tk 8.x
    pack [text .t -wrap none]
    .t configure -tabs {10c 5c}
} -cleanup {
    destroy .t
} -returnCodes {error} -result {tabs must be monotonically increasing, but "5c" is smaller than or equal to the previous tab}
} -returnCodes error -result {tabs must be monotonically increasing, but "5c" is smaller than or equal to the previous tab}
test text-29.4 {tabs - must be positive and must be increasing} -body {
    pack [text .t -wrap none]
    .t insert end "a\tb\tc\td\te"
    catch {.t configure -tabs {10c 5c}}
    update ; update ; update
# This test must simply not go into an infinite loop to succeed
    set result 1
7402
7403
7404
7405
7406
7407
7408
7409

7410
7411
7412
7413
7414
7415
7416
7343
7344
7345
7346
7347
7348
7349

7350
7351
7352
7353
7354
7355
7356
7357







-
+







    for {set i 1} {$i < 20} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t tag delete sel
    .t index sel.first
} -cleanup {
    destroy .t
} -returnCodes {error} -result {text doesn't contain any characters tagged with "sel"}
} -returnCodes error -result {text doesn't contain any characters tagged with "sel"}


test text-32.1 {line heights on creation} -setup {
    text .t
    proc makeText {} {
        set w .g
        set font "Times 11"
7488
7489
7490
7491
7492
7493
7494
7495

7496
7497
7498

7499
7500
7501
7502
7503
7504
7505
7429
7430
7431
7432
7433
7434
7435

7436
7437
7438

7439
7440
7441
7442
7443
7444
7445
7446







-
+


-
+







    .t configure -startline 5
    .pt configure -startline 3
    # the following delete shall not crash
    # (it did before fixing bug 1630262)
    .pt delete 2.0 3.0
    # moreover -startline shall be correct
    # (was wrong before fixing bug 1630262)
    lappend res [.t cget -start] [.pt cget -start]
    lappend res [.t cget -start] [.pt cget -start] [.t get @0,0 "@0,0 lineend"]
} -cleanup {
    destroy .pt
} -result {4 3}
} -result {4 3 {Line 5}}

test text-32.4 {peer widget -start, -endline and deletion (bug 1630262)} -setup {
    destroy .t .pt
    set res {}
} -body {
    text .t
    .t peer create .pt
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
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







-
+






-
+




















-
+








test text-33.1 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer foo 1
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad peer option "foo": must be create or names}
} -returnCodes error -result {bad peer option "foo": must be create or names}
test text-33.2 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer names foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {wrong # args: should be ".t peer names"}
} -returnCodes error -result {wrong # args: should be ".t peer names"}
test text-33.3 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer names
} -cleanup {
    destroy .t
} -returnCodes {ok} -result {}
test text-33.4 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer names
} -cleanup {
    destroy .t
} -result {}
test text-33.5 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
} -body {
    .t peer create foo
} -cleanup {
    destroy .t
} -returnCodes {error} -result {bad window path name "foo"}
} -returnCodes error -result {bad window path name "foo"}
test text-33.6 {TextWidgetCmd procedure, "peer" option} -setup {
    text .t
    set res {}
} -body {
    .t peer create .t2
    lappend res [.t peer names]
    lappend res [.t2 peer names]
7599
7600
7601
7602
7603
7604
7605
7606

7607
7608
7609
7610
7611
7612
7613
7540
7541
7542
7543
7544
7545
7546

7547
7548
7549
7550
7551
7552
7553
7554







-
+







    text .t
    for {set i 1} {$i < 100} {incr i} {
	   .t insert end "Line $i\n"
    }
    .t configure -startline 10 -endline 5
} -cleanup {
    destroy .t
} -returnCodes {error} -result {-startline must be less than or equal to -endline}
} -returnCodes error -result {-startline must be less than or equal to -endline}
test text-33.9 {peer widget -start, -end} -body {
    text .t
    for {set i 1} {$i < 100} {incr i} {
	.t insert end "Line $i\n"
    }
    .t configure -startline 5 -endline 10
} -cleanup {
7786
7787
7788
7789
7790
7791
7792
















7793
7794
7795
7796
7797
7798
7799
7800
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








    set ::my_error
} -cleanup {
    destroy .t
    rename returnerror-37.1 ""
    interp bgerror {} $save
    unset -nocomplain save ::my_error
} -result {}


test text-38.1 {Extending selection with mouse going outside the widget - Bug a9cf210a42} -setup {
    pack [text .t -width 40 -height 10]
    for {set n 1} {$n <= 5} {incr n} {
        .t insert end "This is line $i of text\n"
    }
    update
} -body {
    event generate .t <Button-1> -x 50 -y 50
    event generate .t <B1-Motion> -x 50 -y -50
    .t index sel.first
} -cleanup {
    destroy .t
} -result {1.0}


# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl
# End:
Changes to tests/textBTree.test.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







# 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.
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

253
254
255
256
257
258
259






























































260
261
262
263
264
265
266
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







} -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-2.22 {deleting into beginning of elided range} -setup {
    .t delete 1.0 end
} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 end
    .t delete 5.0 "5.0 + 8 chars"
    .t get 4.0 7.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 4\nine 6\nLine 7\n"
test btree-2.23 {deleting from within elided range} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 8.0
    .t delete 7.0 9.0
    .t get 6.0 8.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 6\nLine 9\n"
test btree-2.24 {deleting whole elided range} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 8.0
    .t delete 5.0 9.0
    .t get 4.0 6.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 4\nLine 9\n"
test btree-2.25 {deleting several elided ranges} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 6.2 6.4 6.5 7.2 7.6
    .t delete 5.0 9.0
    .t get 4.0 7.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 4\nLine 9\nLine 10\n"
test btree-2.26 {deleting first char of elided range} -body {
    for {set n 1} {$n <= 10} {incr n} {
        .t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 end
    .t delete 6.0 6.1
    .t get 5.0 7.0
} -cleanup {
    .t tag delete Elided
    .t delete 1.0 end
} -result "Line 5\nine 6\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}}
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
45
46
47
48
49
50
51
52















53
54

55
56
57
58




59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97

98

99





















100
101
102
103

104





























105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
1
2
3



4
5
6
7
8
9
10
11
12
13



14


15





16







17





18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52




53
54
55
56
57
58
59
60
61
62
63
64
65
66






67




68

69

70

71








72

73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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" }]

# The delay procedure needs to wait long enough for the asynchronous updates
# Platform specific procedure for updating the text widget.

# performed by the text widget to run.
if {[tk windowingsystem] == "aqua"} {
    proc updateText {} {
	update idletasks
    }
    proc delay {} {
proc delay {} {
	update idletasks
	after 100
	update idletasks
    }
} else {
    proc updateText {} {
	update
    update
    }
    proc delay {} {
	update
	after 100
	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
}

# The procedure below is used to generate errors during scrolling commands.

proc scrollError args {
    error "scrolling error"
}

# Return 1 if the two given lists are the same, otherwise return the two lists.
# This is used to compare a test actual result with a test expected result.

proc lequal {res expected} {
    if {[llength $res] != [llength $expected]} {
        return [list "Lengths differ"  result: $res - expected: $expected]
    }
    for {set i 0} {$i < [llength $res]} {incr i} {
        if {[lindex $res $i] ne [lindex $expected $i]} {
	    return [list result: $res - expected: $expected]
	}
    }
    return 1
}

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.
# like border width have selected values.
set twbw 2
set twht 2
option add *Text.borderWidth $twbw
option add *Text.highlightThickness $twht
option add *Text.borderWidth 2         ; # tests work with [1-3]
option add *Text.highlightThickness 2  ; # tests work with [0-5]
option add *Text.padX 1  ; # same padding in x and y, see proc bo; tests work with [0-4]
option add *Text.padY 1  ; # same padding in x and y, see proc bo; tests work with [0-4]

# 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}
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

set varFont {Times -14}
# 16 on XP, 15 on Solaris 8
set varHeight [font metrics $varFont -linespace]
# 13 on XP
set varAscent [font metrics $varFont -ascent]
set varDiff [expr {$varHeight - 15}] ;# 1 on XP

set bigFont {Helvetica -24}
set bigFont {Helvetica -24}  ; # note: not a fixed-width font!
# 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}]
set heightDiff [expr {$bigHeight - $fixedHeight}]

# On Windows at least, the tests do work with {Courier -10}, {Courier -12} or {Courier -14} as fixedFont.
# Warn the user if the actual font is too different from what was requested.
if {[font metrics [font actual $fixedFont] -fixed] != 1} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
does not seem to be a fixed-width font as expected. If this is really the case, many upcoming\
tests will fail."
}
if {$fixedHeight < 12 || $fixedHeight > 17} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedHeight pixels height while the tests expect between 12 and 17 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}
if {$fixedWidth < 6 || $fixedWidth > 8} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedWidth pixels in width while the tests expect between 6 and 8 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}

# Option  -width 20  (characters) below is a fundamental assumption of many
# upcoming tests when wrapping enters in play
# Also  -height 10  (lines) is an important assumption
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 . {}

# full border size of the text widget, i.e. first x or y coordinate inside the text widget
# warning:  -padx  is supposed to be the same as  -pady  (same border size horizontally and
# vertically around the widget)
proc bo {{w .t}} {
    return [expr {[$w cget -borderwidth] + [$w cget -highlightthickness] + [$w cget -padx]}]
}
# x-width of $n chars, fixed width font
proc xw {n} {
    global fixedWidth
    return [expr {$n * $fixedWidth}]
}
# x-coordinate of the first pixel of $n-th char (count starts at zero), left justified
proc xchar {n {w .t}} {
    return [expr {[bo $w] + [xw $n]}]
}
# x-coordinate in widget $w of the first pixel of $n-th char counted from the right, right justified
proc xcharr {n {w .t}} {
    return [expr {[winfo width $w] - [bo $w] - [xw $n]}]
}
# y-coordinate of the first pixel of $l-th display line (count starts at 1)
proc yline {l {w .t}} {
    global fixedHeight
    return [expr {[bo $w] + ($l - 1) * $fixedHeight}]
}
# x-pixels of empty space in widget $w on a line containing $n chars
proc xe {n {w .t}} {
    return [expr {[winfo width $w] - (2 * [bo $w]) - [xw $n]}]
}

# 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
update

# 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
217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258







-
+












-
+













-
+







    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
    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.
    updateText
    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.
    updateText
    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
236
237
238
239
240
241
242
243

244
245

246
247
248
249
250
251
252

253
254
255
256
257
258



259
260
261
262
263
264
265
266
267



268
269
270
271
272
273



274
275
276
277
278
279



280
281
282
283
284
285



286
287
288
289

290
291




292
293
294
295
296
297



298
299
300
301
302
303
304



305
306
307

308

309

310
311

312
313
314
315
316
317
318
319
320






321
322
323
324
325
326




327
328
329
330
331
332
333
334
335
336




337
338
339
340
341
342



343
344
345
346
347
348
349
350
351





352
353
354
355
356
357
358
359
360





361
362
363
364
365
366
367
368
369


370
371



372
373
374
375
376
377
378
379
380
381
382





383
384
385
386
387
388
389
390
391





392
393
394
395
396
397
398
399





400
401
402
403
404
405
406
407
408
409
410


411
412
413

414
415
416




417

418




419

420
421


422
423
424
425
426
427
428
429
430
431
432





433
434
435
436
437
438
439



440
441
442

443
444
445
446
447
448
449
266
267
268
269
270
271
272

273
274

275
276
277
278
279
280
281

282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297


298
299
300
301
302
303
304


305
306
307
308
309
310
311


312
313
314
315
316
317
318


319
320
321
322
323
324
325
326


327
328
329
330
331
332
333
334


335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350

351

352
353

354
355
356
357
358
359




360
361
362
363
364
365
366
367
368
369


370
371
372
373
374
375
376
377
378
379
380
381


382
383
384
385
386
387
388
389


390
391
392
393
394
395
396
397
398
399


400
401
402
403
404
405
406
407
408
409
410
411


412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427


428
429
430
431
432
433
434
435
436
437
438
439


440
441
442
443
444
445
446
447
448
449
450
451


452
453
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







-
+

-
+






-
+





-
+
+
+







-
-
+
+
+




-
-
+
+
+




-
-
+
+
+




-
-
+
+
+




+
-
-
+
+
+
+




-
-
+
+
+






-
+
+
+



+
-
+
-
+

-
+





-
-
-
-
+
+
+
+
+
+




-
-
+
+
+
+








-
-
+
+
+
+




-
-
+
+
+







-
-
+
+
+
+
+







-
-
+
+
+
+
+









+
+
-
-
+
+
+









-
-
+
+
+
+
+







-
-
+
+
+
+
+






-
-
+
+
+
+
+










-
+
+


-
+



+
+
+
+
-
+

+
+
+
+
-
+
-
-
+
+









-
-
+
+
+
+
+






-
+
+
+


-
+







    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]
} [list [expr {[bo]+70}] [expr {[bo]+50}] [expr {[bo]+50}]]
.t tag delete x y z
test textDisp-1.2 {GetStyle procedure, wrapmode} {textfonts} {
test textDisp-1.2 {GetStyle procedure, wrapmode} {
    .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
    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] {}]
} [list [list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 3] $fixedWidth $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} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.2 {LayoutDLine, basics} {
    .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} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.3 {LayoutDLine, basics} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "This isxxx 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.4 {LayoutDLine, word wrap} {textfonts} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.4 {LayoutDLine, word wrap} {
    .t configure -wrap word
    .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 138 5 7 $fixedHeight] [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-2.5 {LayoutDLine, word wrap} {textfonts} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.5 {LayoutDLine, word wrap} {
    .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 [xchar 13] [yline 1] $fixedWidth $fixedHeight] \
} [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 {
        [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
	    [list [xchar 20] [yline 1] 0  $fixedHeight] \
	    [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.6 {LayoutDLine, word wrap} {
    .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} {
} [list [list [xchar 15] [yline 1] [xe 15] $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.7 {LayoutDLine, marks and tags} {
    .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]]
} [list [list [xchar 2] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 1] $fixedWidth $fixedHeight] \
	    [list [xchar 11] [yline 1] $fixedWidth $fixedHeight]]
foreach m [.t mark names] {
    catch {.t mark unset $m}
}
test textDisp-2.8 {LayoutDLine, extra chunk at end of dline} -setup {
scan [wm geom .] %dx%d width height
    scan [wm geom .] %dx%d width height
test textDisp-2.8 {LayoutDLine, extra chunk at end of dline} {textfonts} {
} -body {
    wm geom . [expr {$width+1}]x$height
    updateText
    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 . {}
updateText
test textDisp-2.9 {LayoutDLine, marks and tags} {textfonts} {
} -cleanup {
    wm geom . {}
    update
} -result [list [list [xchar 19] [yline 1] [expr {$fixedWidth+1}] $fixedHeight] \
                [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.9 {LayoutDLine, marks and tags} {
    .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} {
} [list [list [xchar 9] [yline 1] [xe 9] $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	    [list [xchar 15] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.10 {LayoutDLine, marks and tags} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a very_very_long_word_that_wraps."
    .t tag add foo 1.13
    .t tag add foo 1.15
    .t tag add foo 1.17
    .t tag add foo 1.19
    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.11 {LayoutDLine, newline width} {textfonts} {
} [list [list [xchar 9] [yline 1] [xe 9] $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	    [list [xchar 15] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-2.11 {LayoutDLine, newline width} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "a\nbb\nccc\ndddd"
    list [.t bbox 2.2] [.t bbox 3.3]
} [list [list 19 [expr {$fixedDiff + 18}] 126 $fixedHeight] [list 26 [expr {2*$fixedDiff + 31}] 119 $fixedHeight]]
test textDisp-2.12 {LayoutDLine, justification} {textfonts} {
} [list [list [xchar 2] [yline 2] [xe 2] $fixedHeight] \
        [list [xchar 3] [yline 3] [xe 3] $fixedHeight]]
test textDisp-2.12 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 1.0 end
    .t tag add y 3.0 3.2
    list [.t bbox 1.0] [.t bbox 2.0] [.t bbox 4.0] [.t bbox 4.2]
} [list [list 75 5 70 $fixedHeight] [list 71 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 64 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] [list 78 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.13 {LayoutDLine, justification} {textfonts} {
} [list [list [expr {[bo]+[xe 0]/2}] [yline 1] [expr {[xe 0]-[xe 0]/2}] $fixedHeight] \
        [list [expr {[bo]+[xe 1]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 3]/2}] [yline 4] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 3]/2+[xw 2]}] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.13 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify right
    .t tag add x 1.0 end
    .t tag add y 3.0 3.2
    list [.t bbox 1.0] [.t bbox 2.0] [.t bbox 4.0] [.t bbox 4.2]
} [list [list 145 5 0 $fixedHeight] [list 138 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 124 [expr {3*$fixedDiff + 44}] 7 $fixedHeight] [list 138 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.14 {LayoutDLine, justification} {textfonts} {
} [list [list [xcharr 0] [yline 1] 0 $fixedHeight] \
        [list [xcharr 1] [yline 2] $fixedWidth $fixedHeight] \
        [list [xcharr 3] [yline 4] $fixedWidth $fixedHeight] \
        [list [xcharr 1] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.14 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 2.0 3.1
    .t tag configure y -justify right
    .t tag add y 3.0 4.0
    .t tag raise y
    list [.t bbox 2.0] [.t bbox 3.0] [.t bbox 3.end] [.t bbox 4.0]
} [list [list [expr {[bo]+[xe 1]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [xcharr 2] [yline 3] $fixedWidth $fixedHeight] \
} [list [list 71 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 131 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 145 [expr {2*$fixedDiff + 31}] 0 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.15 {LayoutDLine, justification} {textfonts} {
        [list [xcharr 0] [yline 3] 0 $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.15 {LayoutDLine, justification} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "\na\nbb\nccc\ndddd"
    .t tag configure x -justify center
    .t tag add x 2.0 3.1
    .t tag configure y -justify right
    .t tag add y 3.0 4.0
    .t tag lower y
    list [.t bbox 2.0] [.t bbox 3.0] [.t bbox 3.end] [.t bbox 4.0]
} [list [list 71 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 68 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 82 [expr {2*$fixedDiff + 31}] 63 $fixedHeight] [list 5 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.16 {LayoutDLine, justification} {textfonts} {
} [list [list [expr {[bo]+[xe 1]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 2]/2}] [yline 3] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 2]/2+[xw 2]}] [yline 3] [expr {[xe 2]/2}] $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.16 {LayoutDLine, justification} {
    .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} {
} [list [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 4]/2}] [yline 3] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.17 {LayoutDLine, justification} {
    .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} {
} [list [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 17]/2}] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.18 {LayoutDLine, justification} {
    .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
    .t tag add x 2.0
    .t tag add y 3.0
    .t xview scroll 5 units
    list [.t bbox 2.0] [.t bbox 3.0]
} [list [list 26 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 40 [expr {2*$fixedDiff + 31}] 7 $fixedHeight]]
} [list [list [expr {[bo]+[xe 4]/2-[xw 5]}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[xcharr 10]-[xw 5]}] [yline 3] $fixedWidth $fixedHeight]]
.t tag delete x
.t tag delete y
test textDisp-2.19 {LayoutDLine, margins} {textfonts} {
test textDisp-2.19 {LayoutDLine, margins} {
    .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"
    # margins in pixels depend on the font width for more flexibility
    set lm1 [expr {3*$fixedWidth}]
    set lm2 [expr {2*$lm1}]
    set rm [expr {2*$fixedWidth}]
    .t tag configure x -lmargin1 20 -lmargin2 40 -rmargin 15
    .t tag configure x -lmargin1 $lm1 -lmargin2 $lm2 -rmargin $rm
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$lm1}] [yline 1] $fixedWidth $fixedHeight] \
                       [list [expr {[bo]+$lm1+[xw 12]}] [yline 1] [expr {[xe 12]-$lm1}] $fixedHeight] \
                       [list [expr {[bo]+$lm2}] [yline 2] $fixedWidth $fixedHeight] \
                       [list [expr {[bo]+$lm1}] [yline 6] $fixedWidth $fixedHeight]]
    list [.t bbox 1.0] [.t bbox 1.12] [.t bbox 1.13] [.t bbox 2.0]
    lequal [list [.t bbox 1.0] [.t bbox 1.12] [.t bbox 1.13] [.t bbox 2.0]] $expected
} [list [list 25 5 7 $fixedHeight] [list 109 5 36 $fixedHeight] [list 45 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 25 [expr {5*$fixedDiff + 70}] 7 $fixedHeight]]
test textDisp-2.20 {LayoutDLine, margins} {textfonts} {
} {1}
test textDisp-2.20 {LayoutDLine, margins} {
    .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 -lmargin1 20 -lmargin2 10 -rmargin 3
    .t tag configure y -lmargin1 15 -lmargin2 5 -rmargin 0
    .t tag raise y
    .t tag add x 1.0 end
    .t tag add y 1.13
    list [.t bbox 1.0] [.t bbox 1.13] [.t bbox 1.30] [.t bbox 2.0]
} [list [list 25 5 7 $fixedHeight] [list 10 [expr {$fixedDiff + 18}] 7 $fixedHeight] [list 15 [expr {2*$fixedDiff + 31}] 7 $fixedHeight] [list 25 [expr {3*$fixedDiff + 44}] 7 $fixedHeight]]
test textDisp-2.21 {LayoutDLine, margins} {textfonts} {
} [list [list [expr {[bo]+20}] [yline 1] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+5}] [yline 2] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+10}] [yline 3] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+20}] [yline 4] $fixedWidth $fixedHeight]]
test textDisp-2.21 {LayoutDLine, margins} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "Sample text"
    .t tag configure x -lmargin1 80 -lmargin2 80 -rmargin 100
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]
} [list [list 85 5 60 $fixedHeight] [list 85 [expr {$fixedDiff + 18}] 60 $fixedHeight] [list 85 [expr {2*$fixedDiff + 31}] 60 $fixedHeight]]
} [list [list [expr {[bo]+80}] [yline 1] [expr {[xe 0]-80}] $fixedHeight] \
        [list [expr {[bo]+80}] [yline 2] [expr {[xe 0]-80}] $fixedHeight] \
        [list [expr {[bo]+80}] [yline 3] [expr {[xe 0]-80}] $fixedHeight]]
.t tag delete x
.t tag delete y
test textDisp-2.22 {LayoutDLine, spacing options} {textfonts} {
test textDisp-2.22 {LayoutDLine, spacing options} {
    .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]
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558







-
+







    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} {
test textDisp-2.23 {LayoutDLine, spacing options} {
    .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]
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
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







-
+








-
-
+
+


+
+
-
+




+
-
-
-
-
+
+
+
+
+
+
+
+








-
-
-
+
+
+






-
-
+
+



-
-
+
+



-
-
+
+



-
+

-
+








-
+
+
+
+

+
-
+


-
+

-
+


-
+

-
-
+
+
+
+
+
+


-
+


-
+


-
+

-
-
+
+
+
+
+
+


-
+


-
+

-
+
+
+
+

-
+



-
+

+
+
+
-
-
-
+
+
+



-
+



-
+

+
+
+
-
-
+
+










-
+





-
+



-
+


-
+
-
-
+
+
+



-
+
-
-
-
-








-
+





-
+

-
+


-
+


-
+



-
+

-
+


-
+



-
+


-
+
+




-
+

-
+






-
+

-
+








-
+

-
+

-
+












-
+

-
+


-
+


-
+

-
+





-
+

-
+





-
+

-
+


-
+




-
+

-
+


-
-
+
+
+
+
+




-
+

-
+

-
-
+
+
+




-
+


-
+

-
-
+
+
+






-
+

-
+

-
-
+
+
+





-
+

-
+


-
+





-
+


-
-
+
+
+





-
+


+
+
-
-
+
+













-
+


-
+
+
+
+





-





-
+




-
+





-
+

-
+








-
+

-
+









-
+


-
+









-
+


-
+


-
+
+








-
+

-
+



-
+
+






+
-
+



-
+


-
+

-
+




-
+

-
+






-
+




-
+







-
+




-
+


-
+















-
+

-
+




-
-
-
-






-
+
+


-
+

-
+


-
+
+


-
+

-
+

-
-
+
+
+


-
+

-
+

-
-
-
+
+
+
+


-
+

-
+


-
+
+



-
+

-
+


-
+
+



-
+

-
+


-
+
+



-
+

-
+


-
+
+





-
+

-
+




-
+






-
+

-
+

-
+







-
+

-
+








-
+

-
+








-
+

-
+








-
+

-
+








-
+

-
+


-
+





-
+

-
+








-
+

-
+


-
+





-
+

-
+


-
+




-
+

-
+






-
+




-
+

-
+












-
+

-
+


-
+


-
+


-
+


-
+





-
+





-
+
+
+



-
+

-
-
-
-
+
+
+
+
+
+
+
+



-
+

-
+

+
+
-
-
+
+



-
+

-
+

-
+


-
+



-
+

-
+

-
+


-
-
+
+
+
+
+


-
+

-
+

-
+

+
+
+
-
-
+
+



-
+

-
+

-
+


-
+




-
+

-
+


-
+
+
+




-
+

-
+

+
+
-
-
+
+
+
+




-
-
-
+
+
+

+
+
-
-
+
+




-
+


-
+


-
+




-
+

-
+










-
+

-
+












-
+

-
+









-
+







    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} {
test textDisp-2.24 {LayoutDLine, tabs, saving from first chunk} {
    .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} {
} [expr {[bo]+70}]
test textDisp-2.25 {LayoutDLine, tabs, breaking chunks at tabs} {
    .t delete 1.0 end
    .t tag delete x
    # compute a tab width allowing to let 4 tab stops (followed by a single char) on a single line
    set tw [expr {([winfo width .t]-2*[bo]-$fixedWidth)/4}]
    .t tag configure x -tabs [list 30 60 90 120]
    .t tag configure x -tabs [list $tw [expr {$tw*2}] [expr {$tw*3}] [expr {$tw*4}]]
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
    .t tag add x 1.0 end
    set expected [list [expr {[bo]+$tw}] [expr {[bo]+2*$tw}] [expr {[bo]+3*$tw}] [expr {[bo]+4*$tw}]]
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
	    [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]
} [list 35 65 95 125]
test textDisp-2.26 {LayoutDLine, tabs, breaking chunks at tabs} {textfonts} {
    set res [list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
	          [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]]
    lequal $res $expected
} {1}
# Next test is currently constrained to not run on mac (aqua) because on
# aqua it fails due to wrong implementation of tabs with right justification
# (the text is not rendered at all). This is a bug.
test textDisp-2.26 {LayoutDLine, tabs, breaking chunks at tabs} {notAqua} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60 90 120] -justify right
    .t insert 1.0 "a\tb\tc\td\te"
    .t mark set dummy1 1.1
    .t mark set dummy2 1.2
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
	    [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]
} [list 117 124 131 138]
test textDisp-2.27 {LayoutDLine, tabs, calling AdjustForTab} {textfonts} {
	     [lindex [.t bbox 1.6] 0] [lindex [.t bbox 1.8] 0]
} [list [xcharr 4] [xcharr 3] [xcharr 2] [xcharr 1]]
test textDisp-2.27 {LayoutDLine, tabs, calling AdjustForTab} {
    .t delete 1.0 end
    .t tag delete x
    .t tag configure x -tabs [list 30 60]
    .t insert 1.0 "a\tb\tcd"
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0]
} [list 35 65]
test textDisp-2.28 {LayoutDLine, tabs, running out of space in dline} {textfonts} {
} [list [expr {[bo]+30}] [expr {[bo]+60}]]
test textDisp-2.28 {LayoutDLine, tabs, running out of space in dline} {
    .t delete 1.0 end
    .t insert 1.0 "a\tb\tc\td"
    .t bbox 1.6
} [list 5 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-2.29 {LayoutDLine, tabs, running out of space in dline} {textfonts} {
} [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]
test textDisp-2.29 {LayoutDLine, tabs, running out of space in dline} {
    .t delete 1.0 end
    .t insert 1.0 "a\tx\tabcd"
    .t bbox 1.4
} [list 117 5 7 $fixedHeight]
test textDisp-2.30 {LayoutDLine, tabs, running out of space in dline} {textfonts} {
} [list [xchar [expr {2*8}]] [yline 1] $fixedWidth $fixedHeight]
test textDisp-2.30 {LayoutDLine, tabs, running out of space in dline} {
    .t delete 1.0 end
    .t insert 1.0 "a\tx\tabc"
    .t bbox 1.4
} [list 117 5 7 $fixedHeight]
} [list [xchar [expr {2*8}]] [yline 1] $fixedWidth $fixedHeight]

test textDisp-3.1 {different character sizes} {textfonts} {
test textDisp-3.1 {different character sizes} haveBigFontTwiceLargerThanTextFont {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert end "Some sample text, including both large\n"
    .t insert end "characters and\nsmall\n"
    .t insert end "abc\nd\ne\nfghij"
    .t tag add big 1.5 1.10
    .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}]]]
} [list [list [xchar 1] [expr {[yline 1]+$ascentDiff}] $fixedWidth $fixedHeight] \
        [list [expr {[xchar 5]+[font measure $bigFont s]}] [yline 1] [font measure $bigFont a] $bigHeight] \
	[list [bo] [yline 1] [expr {[xw 5]+[font measure $bigFont sampl]+[xw 2]}] $bigHeight $bigAscent] \
	[list [bo] [expr {[bo]+2*$bigHeight+2*$fixedHeight}] [xw 5] $fixedHeight $fixedAscent]]
.t configure -wrap char

test textDisp-4.1 {UpdateDisplayInfo, basic} {textfonts} {
test textDisp-4.1 {UpdateDisplayInfo, basic} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2\nLine 3\n"
    updateText
    update
    .t delete 2.0 2.end
    updateText
    update
    set res $tk_textRelayout
    .t insert 2.0 "New Line 2"
    updateText
    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} {
} [list 2.0 \
        [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
	2.0]
test textDisp-4.2 {UpdateDisplayInfo, re-use tail of text line} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    update
    .t mark set x 2.21
    .t delete 2.2
    updateText
    update
    set res $tk_textRelayout
    .t insert 2.0 X
    updateText
    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} {
} [list 2.0 2.20 \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 1] [yline 3] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 4] $fixedWidth $fixedHeight] \
	{2.0 2.20}]
test textDisp-4.3 {UpdateDisplayInfo, tail of text line shifts} {
    .t delete 1.0 end
    .t insert end "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    update
    .t mark set x 2.21
    .t delete 2.2
    updateText
    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}]
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 4] $fixedWidth $fixedHeight] \
	{2.0 2.20}]
.t mark unset x
test textDisp-4.4 {UpdateDisplayInfo, wrap-mode "none"} {textfonts} {
test textDisp-4.4 {UpdateDisplayInfo, wrap-mode "none"} {
    .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
    update
    list [.t bbox 2.0] [.t bbox 2.25] [.t bbox 3.0] $tk_textRelayout
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        {} \
	[list [xchar 0] [yline 3] $fixedWidth  $fixedHeight] \
} [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"} {
	{1.0 2.0 3.0}]
test textDisp-4.5 {UpdateDisplayInfo, tiny window} {
    if {[tk windowingsystem] eq "win32"} {
	wm overrideredirect . 1
    }
    wm geom . 103x$height
    updateText
    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"
    updateText
    update
    list [.t bbox 2.0] [.t bbox 2.1] [.t bbox 3.0] $tk_textRelayout
} [list [list [xchar 0] [yline 2] 1 $fixedHeight] \
        {} \
	[list [xchar 0] [yline 3] 1 $fixedHeight] \
} [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"} {
	{1.0 2.0 3.0}]
if {[tk windowingsystem] eq "win32"} {
    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"} {
    if {[tk windowingsystem] eq "win32"} {
	wm overrideredirect . 1
    }
    frame .f2 -width 20 -height 100
    pack .f2 -before .f
    wm geom . 103x103
    updateText
    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"
    updateText
    update
    set x [list [.t bbox 1.0] [.t bbox 2.0] $tk_textRelayout]
    wm overrideredirect . 0
    updateText
    update
    set x
} [list [list 5 5 1 1] {} 1.0]
    set expected [list [list [xchar 0] [yline 1] 1 1] {} 1.0]
    lequal $x $expected
} {1}
catch {destroy .f2}
.t configure -borderwidth 0 -wrap char
wm geom . {}
updateText
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"} {
    if {[tk windowingsystem] eq "win32"} {
	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
    update
    .t yview 16.0
    updateText
    update
    set x [list [.t index @0,0] $tk_textRelayout $tk_textRedraw]
    wm overrideredirect . 0
    updateText
    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} failsOnXQuarz {
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
    updateText
    update
    .t delete 5.0 14.0
    updateText
    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} {
test textDisp-4.9 {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
    updateText
    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]]
} [list [list [xchar 0] [yline 3] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 8] $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
    update
    .t delete 13.0 end
    updateText
    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
    updateText
    update
    .t delete 14.0 end
    updateText
    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
    updateText
    update
    .t yview moveto 0
    updateText
    update
    .t yview moveto 1
    updateText
    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
    updateText
    update
    .t yview scroll 3 units
    updateText
    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} failsOnXQuarz {
test textDisp-4.14 {UpdateDisplayInfo, special handling for top/bottom lines} {
    .t tag remove x 1.0 end
    .t yview 1.0
    updateText
    update
    .t yview scroll 3 units
    updateText
    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
    updateText
    update
    .t yview scroll -2 units
    updateText
    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
    updateText
    update
    .t yview scroll -2 units
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 3.0} {2.0 3.0}}
test textDisp-4.17 {UpdateDisplayInfo, horizontal scrolling} {textfonts} {
test textDisp-4.17 {UpdateDisplayInfo, horizontal scrolling} {
    .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
    update
    .t xview scroll 3 units
    updateText
    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} {
} [list {} {1.0 2.0 3.0 4.0} \
        {} \
        [list [expr {[xchar 5]-[xw 3]}] [yline 2] $fixedWidth $fixedHeight] \
	{}]
test textDisp-4.18 {UpdateDisplayInfo, horizontal scrolling} {
    .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
    update
    .t xview scroll 100 units
    updateText
    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} {
} [list {} {1.0 2.0 3.0 4.0} \
        [list [xcharr 19] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-4.19 {UpdateDisplayInfo, horizontal scrolling} {
    .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
    update
    .t xview moveto 0
    .t xview scroll -10 units
    updateText
    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} {
} [list {} {1.0 2.0 3.0 4.0} \
	[list [xchar 5] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-4.20 {UpdateDisplayInfo, horizontal scrolling} {
    .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
    update
    .t delete 2.30 2.44
    updateText
    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} {
} [list 2.0 {1.0 2.0 3.0 4.0} \
        [list [xcharr 5] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-4.21 {UpdateDisplayInfo, horizontal scrolling} {
    .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
    update
    .t xview moveto .6
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {}}
test textDisp-4.22 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {textfonts} {
test textDisp-4.22 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {
    .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
    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} {
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 1] [yline 3] $fixedWidth $fixedHeight]]
test textDisp-4.23 {UpdateDisplayInfo, no horizontal scrolling except for -wrap none} {
    .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
    update
    .t configure -wrap char
    list [.t bbox 2.0] [.t bbox 2.16]
} [list [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 16] [yline 2] $fixedWidth $fixedHeight]]
} [list [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 115 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-5.1 {DisplayDLine, handling of spacing} {textfonts} {

test textDisp-5.1 {DisplayDLine, handling of spacing} {
    .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
    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}]]
} [list 10x4+[xchar 3]+[expr {[yline 1]+8}] \
        10x4+[expr {[xchar 6]+10}]+[expr {[yline 1]+8+($fixedHeight-4)/2}] \
	10x4+[xchar 1]+[expr {[yline 2]+8+2+8+($fixedHeight-4)}] \
	10x4+[expr {[xchar 9]+10}]+[expr {[yline 2]+8+2+8+($fixedAscent-4)}]]
.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
    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} failsOnXQuarz {
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"
    }
    updateText
    update
    .t delete 2.0 3.0
    updateText
    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"
    }
    updateText
    update
    .t insert 2.0 "New Line 2\n"
    updateText
    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"
    }
    updateText
    update
    .t insert 2.end "is so long that it wraps"
    .t insert 4.end "is so long that it wraps"
    updateText
    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"
    }
    updateText
    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"
    updateText
    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} {
test textDisp-6.5 {scrolling in DisplayText, scroll source obscured} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    .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
    update
    .t delete 1.6 1.end
    updateText
    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} {
test textDisp-6.6 {scrolling in DisplayText, Expose events after scroll} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    # 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
    # Line 1 must wrap exactly twice to get the expected result
    .t insert 1.0 "Line 1 is so long that it wraps around, a couple of times"
    .t insert 1.0 "Line 1 is so long that it occupies 3 display lines"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13 14 15} {
	.t insert end "\nLine $i"
    }
    updateText
    update
    .t delete 1.6 1.end
    destroy .f2
    updateText
    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}}
} {{1.0 9.0 10.0} {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
    update
    .t count -update -ypixels 1.0 end
    updateText
    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"
    updateText
    update
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    updateText
    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
    updateText
    update
    set scrollInfo unchanged
    .t insert end xxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n
    .t insert end xxxxxxxxxxxxxxxxxxxxxxxxxx
    updateText
    update
    set scrollInfo
} [list 0.0 [expr {4.0/11}]]
test textDisp-6.10 {DisplayText, redisplay embedded windows after scroll.} {aqua} {
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
    update
    .t delete 2.0 3.0
    updateText
    update
    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} {
test textDisp-7.1 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.2 -relwidth 0.6 -rely 0.22 -relheight 0.55
    updateText
    update
    destroy .f2
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {1.40 2.0 3.0 4.0 5.0 6.0}}
test textDisp-7.2 {TkTextRedrawRegion} {nonPortable} {
test textDisp-7.2 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.5 -rely 0 -relheight 0.5
    updateText
    update
    destroy .f2
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20 1.40 2.0 3.0}}
test textDisp-7.3 {TkTextRedrawRegion} {nonPortable} {
} {{} {1.0 1.20 1.40 2.0 3.0}}
test textDisp-7.3 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.5 -relwidth 0.5 -rely 0.5 -relheight 0.5
    updateText
    update
    destroy .f2
    updateText
    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
} {{} {4.0 5.0 6.0 7.0 8.0}}
test textDisp-7.4 {TkTextRedrawRegion} {aquaKnownBug} {
 # constrained by aquaKnownBug until ticket [aad0231f07] is fixed
   frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0.4 -relwidth 0.2 -rely 0 -relheight 0.2 \
	    -bordermode ignore
    updateText
    update
    destroy .f2
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 1.0 1.20}}
test textDisp-7.5 {TkTextRedrawRegion} {nonPortable} {
test textDisp-7.5 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    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
    update
    destroy .f2
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 7.0 8.0}}
test textDisp-7.6 {TkTextRedrawRegion} {nonPortable} {
test textDisp-7.6 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    frame .f2 -bg #ff0000
    place .f2 -in .t -relx 0 -relwidth 0.2 -rely 0.55 -relheight 0.2 \
	    -anchor w -bordermode ignore
    updateText
    update
    destroy .f2
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.7 {TkTextRedrawRegion} {nonPortable} {
test textDisp-7.7 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    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
    update
    destroy .f2
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{} {borders 3.0 4.0 5.0}}
test textDisp-7.8 {TkTextRedrawRegion} {nonPortable} {
test textDisp-7.8 {TkTextRedrawRegion} {aquaKnownBug} {
# constrained by aquaKnownBug until ticket [aad0231f07] is fixed
    .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
    update
    destroy .f2
    updateText
    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} {
test textDisp-8.1 {TkTextChanged: redisplay whole lines} {
    .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
    update
    .t delete 2.36 2.38
    updateText
    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]]
} [list {2.0 2.18 2.38} {2.0 2.18 2.38} [list [xchar 14] [yline 3] $fixedWidth $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
    update
    .t insert 1.2 xx
    updateText
    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"
    }
    updateText
    update
    .t insert 2.0 xx
    updateText
    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"
    }
    updateText
    update
    .t delete 1.5
    updateText
    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"
    }
    updateText
    update
    .t delete 1.40 1.44
    updateText
    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"
    }
    updateText
    update
    .t delete 1.41 1.44
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{1.0 1.20 1.40} {1.0 1.20 1.40}}
test textDisp-8.7 {TkTextChanged} failsOnXQuarz {
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"
    }
    updateText
    update
    .t delete 1.2 1.end
    updateText
    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"
    }
    updateText
    update
    .t delete 2.2
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {2.0 2.0}
test textDisp-8.9 {TkTextChanged} failsOnXQuarz {
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"
    }
    updateText
    update
    .t delete 2.0 3.0
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 8.0} {2.0 8.0}}
test textDisp-8.10 {TkTextChanged} failsOnUbuntu {
test textDisp-8.10 {TkTextChanged} haveBigFontTwiceLargerThanTextFont {
    .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
    update
    .t delete 2.19
    updateText
    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
    updateText
    update
    set scrollInfo ""
    .t insert end "a\nb\nc\n"
    # We need to wait for our asychronous callbacks to update the
    # scrollbar
    updateText
    update
    .t count -update -ypixels 1.0 end
    updateText
    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
    updateText
    update
    .t mark set insert 8.0        ; # up one line
    updateText
    update
    set res [list $tk_textRedraw]
    .t mark set insert 12.2       ; # in the visible text
    updateText
    update
    lappend res $tk_textRedraw
    .t mark set insert 6.5        ; # in the hidden text
    updateText
    update
    lappend res $tk_textRedraw
    .t mark set insert 3.5        ; # in the visible text again
    updateText
    update
    lappend res $tk_textRedraw
    .t mark set insert 3.8        ; # within the same line
    updateText
    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
    updateText
    update
    .t insert 3.0 ""
    .t delete 1.0 2.0
    update idletasks
} {}

test textDisp-9.1 {TkTextRedrawTag} failsOnUbuntu {
test textDisp-9.1 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .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
    update
    .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} {
    update
   list $tk_textRelayout $tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} -match glob -result {{2.0 2.1[78]} {2.0 2.1[78]}}
test textDisp-9.2 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .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
    update
    .t tag add big 1.2 2.4
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} {{1.0 2.0 2.17} {1.0 2.0 2.17}}
test textDisp-9.3 {TkTextRedrawTag} failsOnUbuntu {
} -match glob -result {{1.0 2.0 2.1[678]} {1.0 2.0 2.1[678]}}
test textDisp-9.3 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .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
    update
    .t tag add big 2.2 2.4
    updateText
    update
    .t tag remove big 1.0 end
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.4 {TkTextRedrawTag} failsOnUbuntu {
test textDisp-9.4 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .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
    update
    .t tag add big 2.2 2.20
    updateText
    update
    .t tag remove big 1.0 end
    updateText
    update
    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
test textDisp-9.5 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -setup {
    .t configure -wrap char -height [expr {[.t cget -height]+10}]
} -body {
    .t delete 1.0 end
    .t insert 1.0 "Line 1\nLine 2 is long enough to wrap around\nLine 3\nLine 4"
    updateText
    update
    .t tag add big 2.2 2.end
    updateText
    update
    .t tag remove big 1.0 end
    updateText
    update
    list $tk_textRelayout $tk_textRedraw
} -cleanup {
    .t configure -height [expr {[.t cget -height]-10}]
    update
} {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.6 {TkTextRedrawTag} failsOnUbuntu {
} -result {{2.0 2.20} {2.0 2.20 eof}}
test textDisp-9.6 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .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
    update
    .t tag add big 2.2 3.5
    updateText
    update
    .t tag remove big 1.0 end
    updateText
    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 {
test textDisp-9.7 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .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
    update
    .t tag remove big 2.19
    updateText
    update
    set tk_textRedraw
} {2.0 2.20 eof}
test textDisp-9.8 {TkTextRedrawTag} {textfonts} {
test textDisp-9.8 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .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
    update
    .t tag add big 2.0 2.5
    updateText
    update
    set tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} {2.0 2.17}
test textDisp-9.9 {TkTextRedrawTag} {textfonts} {
} -match glob -result {2.0 2.1[678]}
test textDisp-9.9 {TkTextRedrawTag} -constraints {
    haveBigFontTwiceLargerThanTextFont
} -body {
    .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
    update
    .t tag add big 1.5 2.5
    update
    set tk_textRedraw
# glob matching is to have some tolerance on actually used font size
# while still testing what we want to test
} {2.0 2.17}
test textDisp-9.10 {TkTextRedrawTag} {
} -match glob -result {2.0 2.1[678]}
test textDisp-9.10 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .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
    update
    set tk_textRedraw none
    .t tag add big 1.3 1.5
    updateText
    update
    set tk_textRedraw
} none
test textDisp-9.11 {TkTextRedrawTag} {
test textDisp-9.11 {TkTextRedrawTag} haveBigFontTwiceLargerThanTextFont {
    .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
    update
    .t tag add big 1.0 2.0
    updateText
    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
    updateText
    update
    .t tag add hidden 3.11 4.6
    updateText
    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
    updateText
    update
    .t tag configure hidden -elide false
    updateText
    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
    updateText
    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
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







-
+

-
+













-
+









-
+


-
+


-
+

-
+

-
+




-
+

-
+


-
+

-
+

-
+




-
+


-
+




-
+


-
+




-
+


-
+


-
+

-
+


-
+


-
+

-
+


-
+




-
+


-
+




-
+


-
+


-
+


-
+


-
+













-
+


-
+

-
+


-
+













-
+


-
+





-
+






-
+





-
+














-
+



















-
+

-
+


-
+

-
+


-
+

-
+







    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
    update
    .t configure -bg black
    updateText
    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
    updateText
    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"
}
updateText
update
test textDisp-11.1 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    .t index @0,0
} {30.0}
test textDisp-11.2 {TkTextSetYView} failsOnXQuarz {
test textDisp-11.2 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    .t yview 32.0
    updateText
    update
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.3 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    .t yview 28.0
    updateText
    update
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.4 {TkTextSetYView} failsOnXQuarz {
test textDisp-11.4 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    .t yview 31.4
    updateText
    update
    list [.t index @0,0] $tk_textRedraw
} {31.0 40.0}
test textDisp-11.5 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    set tk_textRedraw {}
    .t yview -pickplace 31.0
    updateText
    update
    list [.t index @0,0] $tk_textRedraw
} {30.0 {}}
test textDisp-11.6 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    set tk_textRedraw {}
    .t yview -pickplace 28.0
    updateText
    update
    list [.t index @0,0] $tk_textRedraw
} {28.0 {28.0 29.0}}
test textDisp-11.7 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    set tk_textRedraw {}
    .t yview -pickplace 26.0
    updateText
    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} failsOnXQuarz {
test textDisp-11.8 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    set tk_textRedraw {}
    .t yview -pickplace 41.0
    updateText
    update
    list [.t index @0,0] $tk_textRedraw
} {32.0 {40.0 41.0}}
test textDisp-11.9 {TkTextSetYView} failsOnXQuarz {
test textDisp-11.9 {TkTextSetYView} {
    .t yview 30.0
    updateText
    update
    set tk_textRedraw {}
    .t yview -pickplace 43.0
    updateText
    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
    updateText
    update
    set tk_textRedraw {}
    .t yview 10000.0
    updateText
    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
    updateText
    update
    set tk_textRedraw {}
    .t yview 197.0
    updateText
    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} failsOnXQuarz {
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
    updateText
    update
    set tk_textRedraw {}
    .t see 10.30
    updateText
    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"
    }
    updateText
    update
    scan [wm geometry .top] "%dx%d" w2 h2
    wm geometry .top ${w2}x[expr {$h2-2}]
    updateText
    update
    .top.t yview 1.0
    updateText
    update
    set tk_textRedraw {}
    .top.t see 5.0
    updateText
    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"
}
updateText
update
test textDisp-11.14 {TkTextSetYView, only a few lines visible} {
    .top.t yview 5.0
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    update
    .top.t see 21.0
    updateText
    update
    set ind1 [.top.t index @0,0]
    .top.t see end
    updateText
    update
    .top.t see 17.0
    updateText
    update
    set ind2 [.top.t index @0,0]
    .top.t see end
    updateText
    update
    .top.t see 15.0
    updateText
    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
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







-
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+

-
+




-
+

-
+




-
+

-
+





-
+

-
+




-
+

-
+







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
    update
    .top.t see 1.0
    .top.t index @0,[expr {$lineheight - 2}]
} {1.0}
test textDisp-11.22 {TkTextSetYView, peer has -startline} {
    .top.t delete 1.0 end
    for {set i 1} {$i <= 50} {incr i} {
        .top.t insert end "Line $i\n"
    }
    pack [.top.t peer create .top.p] -side left
    pack [scrollbar .top.sb -command {.top.p yview}] -side left -fill y
    .top.p configure -startline 5 -endline 35 -yscrollcommand {.top.sb set}
    update
    .top.p yview moveto 0
    update
    set res [.top.p get @0,0 "@0,0 lineend"]
    destroy .top.p
    set res
} {Line 5}

.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
    update
    .t yview -pickplace 52.0
    updateText
    update
    .t index @0,0
} {49.0}
test textDisp-12.2 {MeasureUp} {
    .t yview 100.0
    updateText
    update
    .t yview -pickplace 53.0
    updateText
    update
    .t index @0,0
} {50.0}
test textDisp-12.3 {MeasureUp} {
    .t yview 100.0
    updateText
    update
    .t yview -pickplace 50.10
    updateText
    update
    .t index @0,0
} {45.0}
.t configure -wrap none
test textDisp-12.4 {MeasureUp} {
    .t yview 100.0
    updateText
    update
    .t yview -pickplace 53.0
    updateText
    update
    .t index @0,0
} {48.0}
test textDisp-12.5 {MeasureUp} {
    .t yview 100.0
    updateText
    update
    .t yview -pickplace 50.10
    updateText
    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
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
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







-
+







-
+







-
+





-
+




-
+










-
-
+
+
+
+
+




-
+








-
-
+
+
+
+
+
+
+
+
+
+





-
+








-
-
+
+
+
+
+
+
+
+
+
+


















-
+
-

-
+

-
+



-
+










-
+









-
+








-
+














-
+


-
+



-
+



-
+



-
+



-
+



-
+


-
+


-
+


-
+







} {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
    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
    updateText
    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
    updateText
    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} {
test textDisp-13.7 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.40
    updateText
    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} {
} [list [list [xchar 10] [yline 6] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 6] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 6] $fixedWidth $fixedHeight] \
	[list [xchar 10] [yline 6] $fixedWidth $fixedHeight]]
test textDisp-13.8 {TkTextSeeCmd procedure} {
    .t xview moveto 0
    .t yview moveto 0
    .t tag add sel 30.20
    .t tag add sel 30.50
    updateText
    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} {
    # contrary to textDisp-13.7 above there is no yview command in this test
    # therefore take into account that the top line is partially hidden
    set y [expr {[yline 6] + [lindex [.t bbox @0,0] 1] - [bo]}]
    set expected [list [list [xchar 10] $y $fixedWidth $fixedHeight] \
                       [list [xchar 19] $y $fixedWidth $fixedHeight] \
                       [list [xchar 19] $y $fixedWidth $fixedHeight] \
                       [list [xchar 10] $y $fixedWidth $fixedHeight]]
    lequal $x $expected
} {1}
test textDisp-13.9 {TkTextSeeCmd procedure} {
    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
    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 74 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 138 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 138 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight] [list 74 [expr {9*$fixedDiff/2 + 66}] 7 $fixedHeight]]
test textDisp-13.10 {TkTextSeeCmd procedure} {} {
    # contrary to textDisp-13.7 above there is no yview command in this test
    # therefore take into account that the top line is partially hidden
    set y [expr {[yline 6] + [lindex [.t bbox @0,0] 1] - [bo]}]
    set expected [list [list [expr {[bo]+round([winfo width .t]-2*[bo])/2}] $y $fixedWidth $fixedHeight] \
                       [list [xcharr 1] $y $fixedWidth $fixedHeight] \
                       [list [xcharr 1] $y $fixedWidth $fixedHeight] \
                       [list [expr {[bo]+round([winfo width .t]-2*[bo])/2}] $y $fixedWidth $fixedHeight]]
    lequal $x $expected
} {1}
test textDisp-13.10 {TkTextSeeCmd procedure} {
    # SF Bug 641778
    set w .tsee
    destroy $w
    text $w -font {Helvetica 8 normal} -bd 16
    $w insert end Hello
    $w see end
    set res [$w bbox end]
    destroy $w
    set res
} {}
test textDisp-13.11 {TkTextSeeCmd procedure} {} {
    # insertion of a character at end of a line containing multi-byte
    # characters and calling see at the line end shall actually show
    # this character
    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
    update
    .top2.t2 see "1.0 lineend"
    updateText
    update
    set ref [.top2.t2 index @0,0]
    .top2.t2 insert "1.0 lineend" ç
    .top2.t2 see "1.0 lineend"
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    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
} {1 {wrong # args: should be ".t xview moveto fraction"}}
test textDisp-14.5 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto a b} msg] $msg
} {1 {wrong # args: should be ".t xview moveto fraction"}}
test textDisp-14.6 {TkTextXviewCmd procedure} {
    list [catch {.t xview moveto a} msg] $msg
} {1 {expected floating-point number but got "a"}}
test textDisp-14.7 {TkTextXviewCmd procedure} failsOnUbuntu {
test textDisp-14.7 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n" ; # 56 chars on this line
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto .3
    .t xview
} [list [expr {118.0/392}] [expr {258.0/392}]]
} [list [expr {round(0.3*(56*$fixedWidth))/(56.0*$fixedWidth)}] [expr {round(0.3*(56*$fixedWidth)+20*$fixedWidth)/(56.0*$fixedWidth)}]]
test textDisp-14.8 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n" ; # 56 chars on this line
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview moveto -.4
    .t xview
} [list 0.0 [expr {5.0/14}]]
} [list 0.0 [expr {20.0/56}]]
test textDisp-14.9 {TkTextXviewCmd procedure} {
    .t delete 1.0 end
    .t insert end xxxxxxxxx\n
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n"
    .t insert end "xxxxx xxxxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx\n" ; # 56 chars on this line
    .t insert end "xxxx xxxxxxxxx xxxxxxxxxxxxx"
    .t xview m 1.4
    .t xview
} [list [expr {9.0/14}] 1.0]
} [list [expr {(56.0-20)/56}] 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"}}
} {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 pages|pixels|units"}}
} {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 floating-point number but got "gorp"}}
} {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
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







-
+














-
+





-
+





-
+





-
+





-
+





-
+





-
+







    .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}}
} {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
    updateText
    update
    .t yview scroll -3 units
    .t index @0,0
} {42.0}
test textDisp-15.2 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    updateText
    update
    .t yview scroll -2 units
    .t index @0,0
} {50.20}
test textDisp-15.3 {ScrollByLines procedure, scrolling backwards} {
    .t yview 51.0
    updateText
    update
    .t yview scroll -4 units
    .t index @0,0
} {49.0}
test textDisp-15.4 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.20
    updateText
    update
    .t yview scroll -2 units
    .t index @0,0
} {49.0}
test textDisp-15.5 {ScrollByLines procedure, scrolling backwards} {
    .t yview 50.40
    updateText
    update
    .t yview scroll -2 units
    .t index @0,0
} {50.0}
test textDisp-15.6 {ScrollByLines procedure, scrolling backwards} {
    .t yview 3.2
    updateText
    update
    .t yview scroll -5 units
    .t index @0,0
} {1.0}
test textDisp-15.7 {ScrollByLines procedure, scrolling forwards} {
    .t yview 48.0
    updateText
    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
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
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







-
+


















-
-
-
+
+
+
+
+
+
+
+
+




-
+















-
+

















-
+
+











-
+
+

+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+






-
+








-
+


-
+

-
-
+
+

-
-
+
+


-
+





-
+


-
+





-
+



-
+
+
+
+
+
+

-
+

-
+



-
+

+
+
-
+


-
+





-
+



-
+

-
+
+
+
+
+
+

-
+
-
-
-
-
-
+


-
+

-
+



-
+




-
+





-
+





-
+







    .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
    update
    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
.t insert 153.end { also has largely enough extra text to wrap.}
update
set totpix [.t count -update -ypixels 1.0 end]
# check that the wrapping lines wrap exactly 6 times in total (4 times for line 151, and twice for line 153),
# this is an assumption of the upcoming tests
if {double(($totpix-5*$heightDiff)/$fixedHeight) != 206.0} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual [.t cget -font]]\",\
is too different from the requested \"[.t cget -font]\". Some of the upcoming tests will probably fail."
}
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)}]
    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
    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
} {4.0}
test textDisp-16.8 {TkTextYviewCmd procedure} {
    list [catch {.t yview bad_mark_name} msg] $msg
} {1 {bad text index "bad_mark_name"}}
test textDisp-16.9 {TkTextYviewCmd procedure, "moveto" option} {
    list [catch {.t yview moveto a b} msg] $msg
} {1 {wrong # args: should be ".t yview moveto fraction"}}
test textDisp-16.10 {TkTextYviewCmd procedure, "moveto" option} {
    list [catch {.t yview moveto gorp} msg] $msg
} {1 {expected floating-point number but got "gorp"}}
test textDisp-16.11 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {
test textDisp-16.11 {TkTextYviewCmd procedure, "moveto" option} haveBigFontTwiceLargerThanTextFont {
# constrained because text tagged with the big font plays a role
    .t yview moveto 0.5
    .t index @0,0
} {103.0}
test textDisp-16.12 {TkTextYviewCmd procedure, "moveto" option} {
    .t yview moveto -1
    .t index @0,0
} {1.0}
test textDisp-16.13 {TkTextYviewCmd procedure, "moveto" option} {
    .t yview moveto 1.1
    .t index @0,0
} {191.0}
test textDisp-16.14 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {
test textDisp-16.14 {TkTextYviewCmd procedure, "moveto" option} {
    # y move to 3/4 of text widget content height
    .t yview moveto .75
    # target y position is inside line 151, which wraps 4 times
    # exactly which display line depends on actual font size
    set ytargetline [expr {150*$fixedHeight+5*$heightDiff}]
    set expected 151.0
    while {[expr {$ytargetline+$fixedHeight}] <= [expr {round(0.75*$totpix)}]} {
        incr ytargetline $fixedHeight
	set expected [.t index "$expected + 1 display line"]
    }
    .t index @0,0
} {151.60}
test textDisp-16.15 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {
    .t yview moveto .752
    .t index @0,0
} {151.60}
test textDisp-16.16 {TkTextYviewCmd procedure, "moveto" option} textfonts {
    lequal [.t index @0,0] $expected
} {1}
test textDisp-16.15 {TkTextYviewCmd procedure, "moveto" option} {
    # y move to 3/4 of text widget content height plus just one line height minus one pixel
    .t yview moveto .75
    set pixtonextline [expr {-[bo] + [lindex [.t bbox @0,0] 1] + [lindex [.t bbox @0,0] 3]}]
    .t yview moveto [expr {0.75 + ($pixtonextline-1)/double($totpix)}]
    # target y position is inside line 151, which wraps 4 times
    # exactly which display line depends on actual font size
    set ytargetline [expr {150*$fixedHeight+5*$heightDiff}]
    set expected 151.0
    while {[expr {$ytargetline+$fixedHeight}] <= [expr {round(0.75*$totpix + ($pixtonextline-1))}]} {
        incr ytargetline $fixedHeight
	set expected [.t index "$expected + 1 display line"]
    }
    lequal [.t index @0,0] $expected
} {1}
test textDisp-16.16 {TkTextYviewCmd procedure, "moveto" option} {
    set count [expr {5 * $bigHeight + 150 * $fixedHeight}]
    set extra [expr {0.04 * double($fixedDiff * 150) / double($count)}]
    .t yview moveto [expr {.753 - $extra}]
    .t index @0,0
} {151.60}
test textDisp-16.17 {TkTextYviewCmd procedure, "moveto" option} failsOnUbuntu {
    # y move to 3/4 of text widget content height plus exactly one line height
    .t yview moveto .75
    set pixtonextline [expr {-[bo] + [lindex [.t bbox @0,0] 1] + [lindex [.t bbox @0,0] 3]}]
    .t yview moveto [expr {0.75 + $pixtonextline/double($totpix)}]
    # target y position is inside line 151, which wraps 4 times
    # exactly which display line depends on actual font size
    set ytargetline [expr {150*$fixedHeight+5*$heightDiff}]
    set expected 151.0
    while {[expr {$ytargetline+$fixedHeight}] <= [expr {round(0.75*$totpix + $pixtonextline)}]} {
        incr ytargetline $fixedHeight
	set expected [.t index "$expected + 1 display line"]
    }
    lequal [.t index @0,0] $expected
} {1}
test textDisp-16.17 {TkTextYviewCmd procedure, "moveto" option} haveBigFontTwiceLargerThanTextFont {
# constrained because text tagged with the big font plays a role
    .t yview moveto .755
    .t index @0,0
} {151.80}
test textDisp-16.18 {TkTextYviewCmd procedure, "moveto" roundoff} {textfonts} {
test textDisp-16.18 {TkTextYviewCmd procedure, "moveto" roundoff} {
    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
    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 pages|pixels|units"}}
} {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 pages|pixels|units"}}
} {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 bogus bogus} msg] $msg
} {1 {bad argument "bogus": must be pages, pixels, or units}}
    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 bogus units} msg] $msg
} {1 {expected floating-point number but got "bogus"}}
    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
    updateText
    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 pages, pixels, or units}}
} {1 {ambiguous argument "p": must be units, pages, or pixels}}
test textDisp-16.23 {TkTextYviewCmd procedure, "scroll" option, back pages} {
    .t yview 50.0
    updateText
    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
    updateText
    update
    .t yview scroll -3 pa
    .t index @0,0
} {1.0}
test textDisp-16.25 {TkTextYviewCmd procedure, "scroll" option, back pages} {
test textDisp-16.25 {TkTextYviewCmd procedure, "scroll" option, back pages} -setup {
    # this frame is needed because some window managers don't allow the overall
    # height of a window to get very narrow, triggering false test failure
    frame .f2 -height 20
    pack .f2 -side top
} -body {
    .t configure -height 1
    updateText
    update
    .t yview 50.0
    updateText
    update
    .t yview scroll -1 pages
    set x [.t index @0,0]
    .t configure -height 10
    updateText
    update
    set x
} -cleanup {
    destroy .f2
} {49.0}
} -result {49.0}
test textDisp-16.26 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 50.0
    updateText
    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
    updateText
    update
    .t yview scroll 2 pages
    .t index @0,0
} {66.0}
test textDisp-16.28 {TkTextYviewCmd procedure, "scroll" option, forward pages} {textfonts} {
test textDisp-16.28 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t yview 98.0
    updateText
    update
    # The man page does not say it but the code does: scrolling 1 page actually uses the
    # window height minus two lines, so that there's some overlap between adjacent pages.
    # Note: it's a bit tricky but we only need to subtract one [bo] from [winfo height .t] here
    # because the origin of @x,y coordinates is at borderwidth start, not at text area start.
    set expected [.t index @0,[expr {[winfo height .t]-[bo]-2*$fixedHeight}]]
    .t yview scroll 1 page
    set res [expr {int([.t index @0,0])}]
    lequal [.t index @0,0] $expected
    if {$fixedDiff > 1} {
	incr res -1
    }
    set res
} 102
} {1}
test textDisp-16.29 {TkTextYviewCmd procedure, "scroll" option, forward pages} {
    .t configure -height 1
    updateText
    update
    .t yview 50.0
    updateText
    update
    .t yview scroll 1 pages
    set x [.t index @0,0]
    .t configure -height 10
    updateText
    update
    set x
} {51.0}
test textDisp-16.30 {TkTextYviewCmd procedure, "scroll units" option} {
    .t yview 45.0
    updateText
    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
    updateText
    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 pages, pixels, or units}}
} {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]
2257
2258
2259
2260
2261
2262
2263
2264

2265
2266
2267
2268
2269
2270
2271
2272
2273

2274
2275
2276
2277
2278
2279
2280
2483
2484
2485
2486
2487
2488
2489

2490
2491
2492
2493
2494
2495
2496
2497
2498

2499
2500
2501
2502
2503
2504
2505
2506







-
+








-
+







} {0 {}}
test textDisp-16.38 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 1.3blah pixels} msg] $msg
} {1 {bad screen distance "1.3blah"}}
test textDisp-16.39 {TkTextYviewCmd procedure} {
    list [catch {.t yview scroll 1.3i pixels} msg] $msg
} {0 {}}
test textDisp-16.40 {text count -xpixels} failsOnUbuntu {
test textDisp-16.40 {text count -xpixels} {
    set res {}
    lappend res [.t count -xpixels 1.0 1.5] \
      [.t count -xpixels 1.5 1.0] \
      [.t count -xpixels 1.0 13.0] \
      [.t count -xpixels 1.0 "1.0 displaylineend"] \
      [.t count -xpixels 1.0 "1.0 lineend"] \
      [.t count -xpixels 1.0 "1.0 displaylineend"] \
      [.t count -xpixels 1.0 end]
} {35 -35 0 42 42 42 0}
} [list [expr {5*$fixedWidth}] [expr {-5*$fixedWidth}] 0 [expr {6*$fixedWidth}] [expr {6*$fixedWidth}] [expr {6*$fixedWidth}] 0]
test textDisp-16.41 {text count -xpixels with indices in elided lines} {
    set res {}
    .t delete 1.0 end
    for {set i 1} {$i < 40} {incr i} {
        .t insert end [string repeat "Line $i" 20]
        .t insert end "\n"
    }
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
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







-
+













-
+










-
+

-
+







        .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
    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
    updateText
    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
    updateText
    update
    .t see [expr {5 + [winfo height .t] / $fixedHeight + 1}].0
    updateText
    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"
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
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







-
+


+
+


+
-
-
-
-
+
+
+
+
+

+
+
+

+


-
+

+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+


+
+


+

+
-
-
-
+
+
+


+
+

+
+


+
+
+

+
-
-
+
+

-
+

+
+
+


+

+
-
-
-
+
+
+
+

+






-
+








-
+





-
+








-
+









-
+










-
+



-
+


-
+


-
+





-
+



-
+













-
+


-
+










+




-
+





-
+


-
+





-
+


-
+






-
+




-
+










-
+











-
+











-
+


-
+








-
+











-
+










-
+










-
+









-
+













-
+







} {1 {expected integer but got "b"}}
test textDisp-17.4 {TkTextScanCmd procedure} {
    list [catch {.t scan stupid -2 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test textDisp-17.5 {TkTextScanCmd procedure} {
    list [catch {.t scan stupid 123 456} msg] $msg
} {1 {bad scan option "stupid": must be mark or dragto}}
test textDisp-17.6 {TkTextScanCmd procedure} {textfonts} {
test textDisp-17.6 {TkTextScanCmd procedure} {
    .t yview 1.0
    .t xview moveto 0
    update
    set expected [.t index @[expr {[bo]+50}],[expr {[bo]+50}]]
    .t scan mark 40 60
    .t scan dragto 35 55
    update
    .t index @0,0
} {4.7}
test textDisp-17.7 {TkTextScanCmd procedure} {textfonts} {
    .t yview 10.0
    lequal [.t index @0,0] $expected
} {1}
test textDisp-17.7 {TkTextScanCmd procedure} {
    # 1st result
    .t yview 1.0
    .t xview moveto 0
    update
    set expected [.t index @[expr {[bo]+20*$fixedWidth-50}],[expr {[bo]+9*$fixedHeight-50}]]
    .t yview 10.0
    .t xview scroll 20 units
    update
    .t scan mark -10 60
    .t scan dragto -5 65
    .t index @0,0
    update
    set x [.t index @0,0]
    # 2nd result
    .t yview 1.0
    .t xview moveto 0
    update
    lappend expected [.t index @[expr {[bo]+20*$fixedWidth-50-50}],[expr {[bo]+9*$fixedHeight-50-70}]]
    .t yview 10.0
    .t xview scroll 20 units
    update
    .t scan mark -10 60
    .t scan dragto -5 65
    update
    .t scan dragto 0 [expr {70 + $fixedDiff}]
    list $x [.t index @0,0]
} {6.12 2.5}
test textDisp-17.8 {TkTextScanCmd procedure} {textfonts} {
    .t scan dragto 0 72
    update
    lequal [list $x [.t index @0,0]] $expected
} {1}
test textDisp-17.8 {TkTextScanCmd procedure} {
    .t yview 1.0
    .t xview moveto 0
    update
    set expected [.t index @[expr {[bo]+50}],[expr {[bo]+50}]]
    .t scan mark 0 60
    .t scan dragto 30 100
    update
    .t scan dragto 25 95
    update
    .t index @0,0
} {4.7}
test textDisp-17.9 {TkTextScanCmd procedure} {textfonts} {
    lequal [.t index @0,0] $expected
} {1}
test textDisp-17.9 {TkTextScanCmd procedure} {
    .t yview end
    .t xview moveto 0
    update
    # this brings us at lower right corner of the text
    .t xview scroll 100 units
    update
    # this does not trigger any scroll, we're already at the corner
    .t scan mark 90 60
    .t scan dragto 10 0
    update
    set expected [.t index @[expr {[winfo width .t]-[bo]-40}],[expr {[winfo height .t]-[bo]-50}]]
    set expected [.t index "$expected - [.t cget -height] lines - [.t cget -width] chars"]
    .t scan dragto 14 5
    update
    .t index @0,0
} {18.44}
    lequal [.t index @0,0] $expected
} {1}
.t configure -wrap word
test textDisp-17.10 {TkTextScanCmd procedure, word wrapping} {textfonts} {
test textDisp-17.10 {TkTextScanCmd procedure, word wrapping} {
    .t yview 10.0
    update
    set origin [.t index @0,0]
    set expected [.t index "$origin - [expr {int(ceil(50.0/$fixedHeight))}] display lines"]
    .t scan mark -10 60
    .t scan dragto -5 65
    update
    set x [.t index @0,0]
    lappend expected [.t index "$origin - [expr {int(ceil((50.0+70.0)/$fixedHeight))}] display lines"]
    .t scan dragto 0 [expr {70 + $fixedDiff}]
    list $x [.t index @0,0]
} {9.0 8.0}
    .t scan dragto 0 72
    update
    lequal [list $x [.t index @0,0]] $expected
} {1}
.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
    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
    updateText
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-18.3 {GetXView procedure} {
    .t configure -wrap none
    .t delete 1.0 end
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    update
    set x {}
    lappend x $scrollInfo
    .t configure -wrap char
    updateText
    update
    lappend x $scrollInfo
    .t configure -wrap word
    updateText
    update
    lappend x $scrollInfo
    .t configure -wrap none
    updateText
    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
    updateText
    update
    set scrollInfo unchanged
    .t insert end xxxxxx\n
    .t insert end xxx
    updateText
    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
    updateText
    update
    .t delete 1.0 end
    .t configure -xscrollcommand scrollError
    updateText
    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
test textDisp-19.1 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    update
    set scrollInfo
} {0.0 1.0}
test textDisp-19.2 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    update
    set scrollInfo "unchanged"
    .t insert 1.0 "Line1\nLine2"
    updateText
    update
    set scrollInfo
} {unchanged}
test textDisp-19.3 {GetYView procedure} {
    .t configure -wrap char
    .t delete 1.0 end
    updateText
    update
    set scrollInfo "unchanged"
    .t insert 1.0 "Line 1\nLine 2 is so long that it wraps around\nLine 3"
    updateText
    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"
    updateText
    update
    set scrollInfo "unchanged"
    foreach i {2 3 4 5 6 7 8 9 10 11 12 13} {
	.t insert end "\nLine $i"
    }
    updateText
    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"
    updateText
    update
    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
    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
    updateText
    update
    set x $scrollInfo
} {0.125 0.75}
test textDisp-19.8 {GetYView procedure} failsOnUbuntu {
test textDisp-19.8 {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 10.end " is really quite long; in fact it's so long that it wraps three times"
    .t yview 2.0
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    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 little bit left on the last line."
    .t yview insert
    updateText
    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 little bit left on the last line."
    .t yview insert
    updateText
    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"} {
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
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







-
+


-
+


-
+







-
+


-
+













-
+

-
+




-
+












-
+






-
+







    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
    update
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    updateText
    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} {
test textDisp-19.13 {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 has enough text to wrap around at least once"
    # Need to wait for asychronous calculations to complete.
    updateText
    update
    scan [wm geom .top] %dx%d twidth theight
    wm geom .top ${twidth}x[expr {$theight - 3}]
    updateText
    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 little bit left on the last line."
    # Need to update so everything is calculated.
    updateText
    update
    .t count -update -ypixels 1.0 end
    updateText
    delay
    set scrollInfo "unchanged"
    .t mark set insert 3.0
    .t tag configure x -background red
    .t tag add x 1.0 5.0
    updateText
    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 little left on the last line."
    updateText
    update
    .t configure -yscrollcommand scrollError
    proc bgerror args {
	global x errorInfo errorCode
	set x [list $args $errorInfo $errorCode]
    }
    .t delete 1.0 end
    updateText
    update
    rename bgerror {}
    .t configure -yscrollcommand scroll
    set x
} {{{scrolling error}} {scrolling error
    while executing
"error "scrolling error""
    (procedure "scrollError" line 2)
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
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







-
+

-
-
+
+
-





-
-
-
+
+
+
+
+
+
+
+








-
+
+

-
+











-
+


-
-
+
+
+
+
+
+
+
+
+









-
+
+

-
+

-
+












-
+










-
+



-
-
+
+


+
+
+
+
+
-
+
-
-
+
+
+



-
-
+
+
+
+



-
+
+
+

-
+



-
+
+
+


-
+

+
-
-
-
+
+
+

-
+

+
-
-
+
+
+
+

-
+





+
-
+







    .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
    update
    .t count -update -ypixels 1.0 end
    updateText
    set res {}
    update
    set res [list \
    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 count -ypixels "16.0 +1 displaylines" "16.0 +4 displaylines +3c"] ]
} [list [expr {20 * $fixedHeight}] \
        [expr {20 * $fixedHeight}] \
	$fixedHeight \
	[expr {2*$fixedHeight}] \
	$fixedHeight \
	[expr {3*$fixedHeight}]]
test textDisp-19.17 {count -ypixels 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
    set res {}
    update
    .t count -update -ypixels 1.0 end
    update
    lappend res \
    set res [list \
      [.t count -ypixels 1.0 6.0] \
      [.t count -ypixels 2.0 7.5] \
      [.t count -ypixels 5.0 8.5] \
      [.t count -ypixels 6.1 6.2] \
      [.t count -ypixels 6.1 18.8] \
      [.t count -ypixels 18.0 20.50] \
      [.t count -ypixels 5.2 20.60] \
      [.t count -ypixels 20.60 20.70] \
      [.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 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} {
} [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} {
    .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
    .t count -update -ypixels 1.0 end
    update
    lappend res [.t count -ypixels 5.0 25.0]
    set res [.t count -ypixels 5.0 25.0]
    .t yview scroll [expr {- 15 * $fixedHeight}] pixels
    updateText
    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
    updateText
    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} failsOnUbuntu {
test textDisp-20.1 {FindDLine} {
    .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 {
} [list {} {} [list [bo] [yline 2] [xw 7] $fixedHeight $fixedAscent] {}]
test textDisp-20.2 {FindDLine} {
    .t yview 100.0
    .t yview -pickplace 53.0
    set centlineY [lindex [.t bbox 53.0] 1]
    set expectedY [expr {$centlineY - int(($centlineY-[bo])/$fixedHeight)*$fixedHeight - $fixedHeight}]
    set expected [list [list [bo] $expectedY [xw 20] $fixedHeight $fixedAscent] \
                       [list [bo] $expectedY [xw 20] $fixedHeight $fixedAscent] \
	               [list [bo] [expr {$expectedY+$fixedHeight}] [xw 19] $fixedHeight $fixedAscent]]
    list [.t dlineinfo 50.0] [.t dlineinfo 50.14] [.t dlineinfo 50.21]
    set res [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 {
    lequal $res $expected
} {1}
test textDisp-20.3 {FindDLine} {
    .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 {
} [list [list [bo] [yline 2] [xw 20] $fixedHeight $fixedAscent] \
        [list [bo] [yline 3] [xw 19] $fixedHeight $fixedAscent] \
	{}]
test textDisp-20.4 {FindDLine} {
    .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}]] {}]
} [list [list [bo] [yline 9] [xw 20] $fixedHeight $fixedAscent] \
        [list [bo] [yline 10] [xw 19] $fixedHeight $fixedAscent] \
	{}]
.t config -wrap none
test textDisp-20.5 {FindDLine} failsOnUbuntu {
test textDisp-20.5 {FindDLine} {
    .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}]]]
} [list [list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent] \
        [list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent] \
	[list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent]]

.t config -wrap word
test textDisp-21.1 {TkTextPixelIndex} {textfonts} {
test textDisp-21.1 {TkTextPixelIndex} {
    .t yview 48.0
    set off [expr {[bo]+3}]
    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}
    list [.t index @-10,-10] [.t index @$off,$off] [.t index @[expr {[xchar 2]+2}],$off] \
	    [.t index @[expr {[xchar 14]+1}],$off] [.t index @[xchar 5],[yline 5]]
} {48.0 48.0 48.2 48.7 50.45}
.t insert end \n
test textDisp-21.2 {TkTextPixelIndex} {textfonts} {
test textDisp-21.2 {TkTextPixelIndex} {
    .t yview 195.0
    set off [expr {[xchar 1]+1}]
    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]
    list [.t index @$off,[expr {[yline 6]+2}]] \
         [.t index @$off,[expr {[yline 7]+2}]] \
	 [.t index @$off,[expr {[yline 8]+2}]] \
	 [.t index @$off,1002]
} {197.1 198.1 199.1 201.0}
test textDisp-21.3 {TkTextPixelIndex, horizontal scrolling} {textfonts} {
test textDisp-21.3 {TkTextPixelIndex, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"
    .t insert end "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    .t xview scroll 2 units
    set off [expr {[yline 1]+4}]
    list [.t index @-5,7] [.t index @5,7] [.t index @33,20]
    list [.t index @-5,$off] [.t index @[expr {[xchar 1]-2}],$off] [.t index @[expr {[xchar 4]+2}],[expr {[yline 2]+2}]]
} {1.2 1.2 2.6}
test textDisp-21.4 {count -displaylines regression} {
    set message {
   QOTW:  "C/C++, which is used by 16% of users, is the most popular programming language, but Tcl, used by 0%, seems to be the language of choice for the highest scoring users."
(new line)
Use the Up (cursor) key to scroll up one line at a time.  At the second press, the cursor either gets locked or jumps several lines.

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
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







-
+

-
+




-
-
+
+
+
+
+
+



-
-
+
+
+
+
+
+
+



-
-
+
+
+
+
-
-
+
+
+
+
+



-
-
+
+
+
+
-
-
+
+
+
+


-
-
+
+

-
-
+
+
+
+
+




-
-
+
+
+
+
+
-
+

-
-
+
+



-
+

-
+
+

-
+







-
-
+
+
+
+
+
+
+













-
+


-
+
+
+
+
+
+

-
+








-
+













-
+







-
+













-
-
+
+




-
-
-
-
+
+
+
+
+
+
+
+


-
+

-
+

-
+


-
-
+
+
+
+
+
+



-
-
+
+
+
+
-
-
+
+
+
+
+



-
-
+
+
+
+
-
+

-
-
+
+






-
+

-
+
+
+

-
+










-
+
+
+


-
+




-
-
+
+
+
+
+
+



+
+
+
+
+
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+




-
-
+
+
+
+
-
-
+
+




-
+

+
-
-
+
+
+



+
+
+
-
-
+
+

+
-
-
+
+
+




-
+

-
-
+
+
+
+
+
+



+
+
+
+
+
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+




-
-
+
+
+
+
-
-
+
+
+
+
+




-
-
+
+
+
+
-
-
+
+
+
+
+




-
-
+
+
+
+
-
-
+
+



+
+
-
-
+
+
-
-
+


+
+
-
-
+
+
+
+
+





+
+
-
+
-
-
+
+




-
+

-
-
+
+
+
+
+




-
-
+
+
+
+
-
-
+
+
+
+
+




-
-
+
+
+
+
-
-
-
+
+
+





+
+
-
-
+
+

+
-
-
+
+
+


-
+




-
+

-
-
+
+
+




-
-
-
-
+
+
+
+
+
+
+




-
+

-
-
+
+
+
+








-
+



+
+
+
-
+
+
+

-
-
+
+






-
-
+
+






-
-
-
+
+
+


-
+





-
+


-
-
+
+
+
+
+





-
-
+
+
+




-
-
+
+
+
+
+


-
+

-
+

-
-
+
+



-
+
+
+

-
+

-
-
+
+




-
-
+
+
+
+







-
+
+
+







.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
update
.t tag add x 50.1
test textDisp-22.1 {TkTextCharBbox} {textfonts} {
test textDisp-22.1 {TkTextCharBbox} {
    .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} {
} [list {} \
        [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 3] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 5] $fixedWidth $fixedHeight] \
	{}]
test textDisp-22.2 {TkTextCharBbox} {
    .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} {
} [list [list [xchar 5] [yline 3] $fixedWidth $fixedHeight] \
        {} \
	[list [xchar 0] [yline 10] $fixedWidth $fixedHeight]]
test textDisp-22.3 {TkTextCharBbox, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 1] [yline 10] $fixedWidth $fixedHeight] \
                       [list [xchar 1] [yline 11] $fixedWidth [expr {($height-1)-$oriHeight}]]]
    lequal [list [.t bbox 19.1] [.t bbox 20.1]] $expected
} [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} {
} {1}
test textDisp-22.4 {TkTextCharBbox, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 1] [yline 10] $fixedWidth $fixedHeight] \
                       [list [xchar 1] [yline 11] $fixedWidth [expr {($height+1)-$oriHeight}]]]
    lequal [list [.t bbox 19.1] [.t bbox 20.1]] $expected
} [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} {
} {1}
test textDisp-22.5 {TkTextCharBbox, cut-off char} {
    wm geometry . {}
    update
    .t config -wrap none
    .t yview 10.0
    wm geom . [expr {$width-95}]x$height
    updateText
    wm geom . [expr {$width-(20-7)*$fixedWidth}]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} {
} [list [xchar 6] [yline 6] $fixedWidth $fixedHeight]
test textDisp-22.6 {TkTextCharBbox, line visible but not char} haveBigFontTwiceLargerThanTextFont {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 1] [yline 10] $fixedWidth $fixedHeight] \
                       {} \
	               [list [xchar 2] [yline 11] [font measure $bigFont "n"] [expr {($height+3)-$oriHeight}]]]
    lequal [list [.t bbox 19.1] [.t bbox 20.1] [.t bbox 20.2]] $expected
} [list [list 10 [expr {3+9*$fixedHeight}] 7 $fixedHeight] {} [list 17 [expr {3+10*$fixedHeight}] 14 7]]
} {1}
wm geom . {}
updateText
test textDisp-22.7 {TkTextCharBbox, different character sizes} {textfonts} {
update
test textDisp-22.7 {TkTextCharBbox, different character sizes} haveBigFontTwiceLargerThanTextFont {
    .t config -wrap char
    .t yview 10.0
    .t tag add big 12.2 12.5
    updateText
    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]]
} [list [list [xchar 1] [expr {[yline 3]+$ascentDiff}] $fixedWidth $fixedHeight] \
        [list [xchar 2] [yline 3] [font measure $bigFont "n"] $bigHeight]]
.t tag remove big 1.0 end
test textDisp-22.8 {TkTextCharBbox, horizontal scrolling} {textfonts} {
test textDisp-22.8 {TkTextCharBbox, horizontal scrolling} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert end "12345\n"
    .t insert end "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    .t xview scroll 4 units
    list [.t bbox 1.3] [.t bbox 1.4] [.t bbox 2.3] [.t bbox 2.4] \
	    [.t bbox 2.23] [.t bbox 2.24]
} [list {} [list 3 3 7 $fixedHeight] {} [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight] [list 136 [expr {$fixedDiff + 16}] 7 $fixedHeight] {}]
test textDisp-22.9 {TkTextCharBbox, handling of spacing} {textfonts} {
} [list {} \
        [list [xchar 0] [yline 1] $fixedWidth $fixedHeight] \
	{} \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 19] [yline 2] $fixedWidth $fixedHeight] \
	{}]
test textDisp-22.9 {TkTextCharBbox, handling of spacing} {
    .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
    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]]
} [list [list [xchar 3] [expr {[yline 1]+8}] 10 4] \
        [list [expr {[xchar 3]+10+[xw 3]}] [expr {[yline 1]+8+($fixedHeight-4)/2}] 10 4] \
	[list [xchar 1] [expr {[yline 2]+8+2+8+($fixedHeight-4)}] 10 4] \
	[list [expr {[xchar 1]+10+[xw 8]}] [expr {[yline 2]+8+2+8+($fixedAscent-4)}] 10 4] \
	[list [xchar 1] [expr {[yline 1]+8}] $fixedWidth $fixedHeight] \
	[list [expr {[xchar 1]+10+[xw 7]}] [expr {[yline 2]+8+2+8}] $fixedWidth $fixedHeight]]
.t tag delete spacing
test textDisp-22.10 {TkTextCharBbox, handling of elided lines} {textfonts} {
test textDisp-22.10 {TkTextCharBbox, handling of elided lines} {
    .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
    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} {
test textDisp-22.11 {TkTextCharBbox, handling of wrapped elided lines} {
    .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
    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"
updateText
test textDisp-23.1 {TkTextDLineInfo} {textfonts} {
update
test textDisp-23.1 {TkTextDLineInfo} {
    .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
} [list {} \
        [list [bo] [yline 1] [xw 7] $fixedHeight $fixedAscent] \
	[list [bo] [yline 5] [xw 13] $fixedHeight $fixedAscent] \
	{}]
.t config -bd 4
test textDisp-23.2 {TkTextDLineInfo} {
    .t config -wrap word
    update
    .t yview 48.0
    .t dlineinfo 50.40
} [list 7 [expr {4*$fixedDiff + 59}] 91 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]
} [list [bo] [yline 5] [xw 13] $fixedHeight $fixedAscent]
.t config -bd 0
test textDisp-23.3 {TkTextDLineInfo} {textfonts} {
test textDisp-23.3 {TkTextDLineInfo} {
    .t config -wrap none
    updateText
    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} {
} [list [list [bo] [yline 3] [xw 53] $fixedHeight $fixedAscent] \
        [list [bo] [yline 10] [xw 7] $fixedHeight $fixedAscent]]
test textDisp-23.4 {TkTextDLineInfo, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [bo] [yline 10] [xw 7] $fixedHeight $fixedAscent] \
                       [list [bo] [yline 11] [xw 7] [expr {($height-1)-$oriHeight}] $fixedAscent]]
    lequal [list [.t dlineinfo 19.0] [.t dlineinfo 20.0]] $expected
} [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} {
} {1}
test textDisp-23.5 {TkTextDLineInfo, cut-off lines} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [bo] [yline 10] [xw 7] $fixedHeight $fixedAscent] \
                       [list [bo] [yline 11] [xw 7] [expr {($height+1)-$oriHeight}] $fixedAscent]]
    lequal [list [.t dlineinfo 19.0] [.t dlineinfo 20.0]] $expected
} [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}]]]
} {1}
wm geom . {}
updateText
test textDisp-23.6 {TkTextDLineInfo, horizontal scrolling} {textfonts} {
update
test textDisp-23.6 {TkTextDLineInfo, horizontal scrolling} {
    .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
    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}]]]
} [list [list [expr {[xw -6]+[bo]}] [yline 1] [xw 10] $fixedHeight $fixedAscent] \
        [list [expr {[xw -6]+[bo]}] [yline 2] [xw 52] $fixedHeight $fixedAscent] \
	[list [expr {[xw -6]+[bo]}] [yline 3] [xw 5] $fixedHeight $fixedAscent]]
.t xview moveto 0
test textDisp-23.7 {TkTextDLineInfo, centering} {textfonts} {
test textDisp-23.7 {TkTextDLineInfo, centering} {
    .t config -wrap word
    .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 tag configure x -justify center
    .t tag configure y -justify right
    .t tag add x 1.0
    .t tag add y 3.0
    list [.t dlineinfo 1.0] [.t dlineinfo 2.0] [.t dlineinfo 3.0]
} [list [list 38 3 70 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 3 [expr {$fixedDiff + 16}] 119 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]] [list 108 [expr {4*$fixedDiff + 55}] 35 [expr {$fixedDiff + 13}] [expr {$fixedDiff + 10}]]]
} [list [list [expr {[bo]+[xe 10]/2}] [yline 1] [xw 10] $fixedHeight $fixedAscent] \
        [list [bo] [yline 2] [xw 17] $fixedHeight $fixedAscent] \
	[list [xcharr 5] [yline 5] [xw 5] $fixedHeight $fixedAscent]]
.t tag delete x y

test textDisp-24.1 {TkTextCharLayoutProc} {textfonts} {
test textDisp-24.1 {TkTextCharLayoutProc} {
    .t configure -wrap char
    .t delete 1.0 end
    .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} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.2 {TkTextCharLayoutProc} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    # be tolerant about borderwidth et al. - don't let another char fit on the line
    set wi $width
    while {$wi+1-$oriWidth >= $fixedWidth} {
        incr wi -$fixedWidth
    }
    wm geom . [expr {$width+1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
    wm geom . [expr {$wi+1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($wi+1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.3 {TkTextCharLayoutProc} {textfonts} {
} {1}
test textDisp-24.3 {TkTextCharLayoutProc} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($width-1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.4 {TkTextCharLayoutProc, newline not visible} {textfonts} {
} {1}
test textDisp-24.4 {TkTextCharLayoutProc, newline not visible} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 01234567890123456789\n012345678901234567890
    wm geom . {}
    updateText
    update
    list [.t bbox 1.19] [.t bbox 1.20] [.t bbox 2.20]
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
} [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} {
        [list [xchar 20] [yline 1] 0 $fixedHeight] \
	[list [xchar 0] [yline 3] $fixedWidth $fixedHeight]]
test textDisp-24.5 {TkTextCharLayoutProc, char doesn't fit, newline not visible} {nonwin} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 0\n1\n
    # set text widget width to 1-char width minus [bo] pixels
    # note: windows refuses to shrink enough therefore the constraint
    set wi [expr {[winfo width .f]+[bo]+[xw 1]}]
    wm geom . 110x$height
    updateText
    wm geom . ${wi}x$height
    update
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 2.0]
} [list [list [xchar 0] [yline 1] [expr {$fixedWidth-[bo]}] $fixedHeight] \
} [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} {
        [list [expr {[xchar 1]-[bo]}] [yline 1] 0 $fixedHeight] \
	[list [xchar 0] [yline 2] [expr {$fixedWidth-[bo]}] $fixedHeight]]
test textDisp-24.6 {TkTextCharLayoutProc, line ends with space} {
    .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
    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} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.7 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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"
    # be tolerant about borderwidth et al. - don't let another char fit on the line
    set wi $width
    while {$wi+1-$oriWidth >= $fixedWidth} {
        incr wi -$fixedWidth
    }
    wm geom . [expr {$width+1}]x$height
    updateText
    list [.t bbox 1.19] [.t bbox 1.20]
    wm geom . [expr {$wi+1}]x$height
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($wi+1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [list [list 136 3 12 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.8 {TkTextCharLayoutProc, line ends with space} {textfonts} {
} {1}
test textDisp-24.8 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($width-1-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [list [list 136 3 10 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.9 {TkTextCharLayoutProc, line ends with space} {textfonts} {
} {1}
test textDisp-24.9 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($width-6-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [list [list 136 3 5 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.10 {TkTextCharLayoutProc, line ends with space} {textfonts} {
} {1}
test textDisp-24.10 {TkTextCharLayoutProc, line ends with space} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 19] [yline 1] [expr {$fixedWidth+($width-7-$oriWidth)}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [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} {
} {1}
test textDisp-24.11 {TkTextCharLayoutProc, line ends with space that doesn't quite fit} {
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "01234567890123456789 \nabcdefg"
    # set text widget width to 2 pixels more than 20-char width
    set wi [expr {[winfo width .f]+2*[bo]+[xw 20]+2}]
    wm geom . [expr {$width-2}]x$height
    updateText
    wm geom . ${wi}x$height
    update
    set result {}
    lappend result [.t bbox 1.21] [.t bbox 2.0]
    set result [list [.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 [expr {[xchar 20]+2}] [yline 1] 0 $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
} [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} {
	[list [expr {[xchar 20]+2}] [yline 1] 0 $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
wm geom . {}
update
test textDisp-24.12 {TkTextCharLayoutProc, tab causes wrap} {
    .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
    set expected [list [list [expr {[xchar 0]+2*8*$fixedWidth}] [yline 1] [expr {[winfo width .t]-([xchar 0]+2*8*$fixedWidth)-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    list [.t bbox {insert -1c}] [.t bbox insert]
    lequal [list [.t bbox {insert -1c}] [.t bbox insert]] $expected
} [list [list 115 3 30 $fixedHeight] [list 3 [expr {$fixedDiff + 16}] 7 $fixedHeight]]
test textDisp-24.13 {TkTextCharLayoutProc, -wrap none} {textfonts} {
} {1}
test textDisp-24.13 {TkTextCharLayoutProc, -wrap none} {
    .t configure -wrap none
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    wm geom . {}
    updateText
    update
    list [.t bbox 1.19] [.t bbox 1.20]
} [list [list 136 3 7 $fixedHeight] {}]
test textDisp-24.14 {TkTextCharLayoutProc, -wrap none} {textfonts} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] {}]
test textDisp-24.14 {TkTextCharLayoutProc, -wrap none} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
                       [list [xchar 20] [yline 1] [expr {$width+1-$oriWidth}] $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [list [list 136 3 7 $fixedHeight] [list 143 3 5 $fixedHeight]]
test textDisp-24.15 {TkTextCharLayoutProc, -wrap none} {textfonts} {
} {1}
test textDisp-24.15 {TkTextCharLayoutProc, -wrap none} {
    wm geometry . {}
    update
    scan [wm geom .] %dx%d oriWidth oriHeight
    .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]
    update
    set expected [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
                       [list [xchar 20] [yline 1] [expr {$width-1-$oriWidth}] $fixedHeight]]
    lequal [list [.t bbox 1.19] [.t bbox 1.20]] $expected
} [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"} {
} {1}
test textDisp-24.16 {TkTextCharLayoutProc, no chars fit} {
    if {[tk windowingsystem] eq "win32"} {
	wm overrideredirect . 1
    }
    .t configure -wrap char
    .t delete 1.0 end
    .t insert 1.0 "abcdefghijklmnopqrstuvwxyz"
    # set text widget width to [bo] pixels (no chars fit in the widget at all)
    set wi [expr {[winfo width .f]+[bo]}]
    wm geom . 103x$height
    updateText
    wm geom . ${wi}x$height
    update
    list [.t bbox 1.0] [.t bbox 1.1] [.t bbox 1.2]
} [list [list [xchar 0] [yline 1] 1 $fixedHeight] \
} [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"} {
        [list [xchar 0] [yline 2] 1 $fixedHeight] \
	[list [xchar 0] [yline 3] 1 $fixedHeight]]
if {[tk windowingsystem] eq "win32"} {
    wm overrideredirect . 0
}
test textDisp-24.17 {TkTextCharLayoutProc, -wrap word} {textfonts} {
test textDisp-24.17 {TkTextCharLayoutProc, -wrap word} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "This is a line that wraps around"
    wm geom . {}
    updateText
    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} {
} [list [list [xchar 19] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.18 {TkTextCharLayoutProc, -wrap word} {
    .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} {
    update
    list [.t bbox 1.15] [.t bbox 1.16] [.t bbox 1.17] [.t bbox 1.21]
} [list [list [xchar 15] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 16] [yline 1] [xe 16] $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight] \
	[list [xchar 4] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-24.19 {TkTextCharLayoutProc, -wrap word} {
    .t configure -wrap word
    .t delete 1.0 end
    .t insert 1.0 "xxThis is a line that wraps around"
    wm geom . {}
    updateText
    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} {
} [list [list [xchar 14] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar 15] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar 16] [yline 1] [xe 16] $fixedHeight]]
test textDisp-24.20 {TkTextCharLayoutProc, vertical offset} {
    .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
    .t tag configure up -offset -2
    lappend result [.t bbox 2.1] [.t dlineinfo 2.1]
    .t tag delete up
    set result
} [list [list [xchar 1] [yline 2] $fixedWidth $fixedHeight] \
        [list [bo] [yline 2] [xw 6] $fixedHeight $fixedAscent] \
	[list [xchar 1] [yline 2] $fixedWidth $fixedHeight] \
} [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}]]]
        [list [bo] [yline 2] [xw 6] [expr {$fixedHeight+6}] [expr {$fixedAscent+6}]] \
	[list [xchar 1] [expr {[yline 2]+2}] $fixedWidth $fixedHeight] \
        [list [bo] [yline 2] [xw 6] [expr {$fixedHeight+2}] $fixedAscent]]
.t configure -width 30
updateText
test textDisp-24.21 {TkTextCharLayoutProc, word breaks} {textfonts} {
update
test textDisp-24.21 {TkTextCharLayoutProc, word breaks} {
    .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
} [list 3 [expr {$fixedDiff/2 + 19}] 7 $fixedHeight]
test textDisp-24.22 {TkTextCharLayoutProc, word breaks} {textfonts} {
} [list [xchar 0] [expr {[yline 2]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]
test textDisp-24.22 {TkTextCharLayoutProc, word breaks} {
    .t configure -wrap word
    .t delete 1.0 end
    frame .t.f -width 30 -height 20 -bg black
    .t insert 1.0 "Sample text xxxxxxx yyyyyyy"
    .t window create end -window .t.f
    .t insert end "zzzzzzz qqqqq rrrr ssss tt u vvvvv"
    .t bbox 1.28
} [list 33 [expr {$fixedDiff/2 + 19}] 7 $fixedHeight]
test textDisp-24.23 {TkTextCharLayoutProc, word breaks} {textfonts} {
   .t bbox 1.28
} [list [expr {[bo]+30}] [expr {[yline 2]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight]
test textDisp-24.23 {TkTextCharLayoutProc, word breaks} {
    .t configure -wrap word
    .t delete 1.0 end
    frame .t.f -width 30 -height 20 -bg black
    frame .t.f -width 50 -height 20 -bg black
    .t insert 1.0 "Sample text xxxxxxx yyyyyyy "
    .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]
} [list [xchar 0] [yline 3] 50 20]
catch {destroy .t.f}
.t configure -width 20
updateText
test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {textfonts} {
update
# Next test is currently constrained to not run on mac (aqua) because on
# aqua it fails due to wrong implementation of tabs with right justification
# (the text is not rendered at all). This is a bug.
test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} notAqua {
    .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 {
} [list [list [expr {[bo]+[xe 8]/2}] [yline 1] $fixedWidth $fixedHeight] \
        [list [expr {[bo]+[xe 8]/2+[xw 7]}] [yline 1] $fixedWidth $fixedHeight]]
test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -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]
    update
    set expected [list [list [expr {[bo .tt]+40-$fixedWidth}] [yline 1 .tt] $fixedWidth $fixedHeight] \
                       [list [expr {[bo .tt]+40-$fixedWidth}] [yline 2 .tt] $fixedWidth $fixedHeight] \
                       [list [expr {[bo .tt]+40-$fixedWidth}] [yline 3 .tt] $fixedWidth $fixedHeight]]
    lequal [list [.tt bbox 1.1] [.tt bbox 2.2] [.tt bbox 3.3]] $expected
} -cleanup {
    destroy .tt
} -result [list [list 38 5 7 $fixedHeight] [list 38 20 7 $fixedHeight] [list 38 35 7 $fixedHeight]]
} -result {1}

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 \
    -tabs 100
updateText
test textDisp-25.1 {CharBboxProc procedure, check tab width} {textfonts} {
update
test textDisp-25.1 {CharBboxProc procedure, check tab width} {
    .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]]
} [list [list [xchar 3] [yline 1] [expr {100-3*$fixedWidth}] $fixedHeight] \
        [list [expr {[bo]+100+$fixedWidth}] [yline 1] [expr {200-(100+$fixedWidth)}] $fixedHeight] \
	[list [expr {[bo]+200}] [yline 1] $fixedWidth $fixedHeight]]

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 -pady 0 \
	-tabs {}
updateText
test textDisp-26.1 {AdjustForTab procedure, no tabs} {textfonts} {
update
test textDisp-26.1 {AdjustForTab procedure, no tabs} {
    .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} {
} [list [expr {[bo]+8*$fixedWidth}] \
        [expr {[bo]+2*8*$fixedWidth+2*$fixedWidth}] \
	[expr {[bo]+3*8*$fixedWidth}]]
test textDisp-26.1.2 {AdjustForTab procedure, no tabs} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    .t configure -tabstyle wordprocessor
    set res [list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.12] 0] \
      [lindex [.t bbox 1.14] 0]]
    .t configure -tabstyle tabular
    set res
} [list 56 168 224]
} [list [expr {[bo]+8*$fixedWidth}] \
        [expr {[bo]+3*8*$fixedWidth}] \
	[expr {[bo]+4*8*$fixedWidth}]]
test textDisp-26.2 {AdjustForTab procedure, not enough tabs specified} {
    .t delete 1.0 end
    .t insert 1.0 a\tb\tc\td
    .t tag delete x
    .t tag configure x -tabs 40
    .t tag add x 1.0 end
    list [lindex [.t bbox 1.2] 0] [lindex [.t bbox 1.4] 0] \
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
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







-
+


-
+



+
+
+
+
-
+

+
-
-
-
-
+
+
+
+
+



+
+
+
+
-
+

+



-
-
-
+
+
+







-
-
+
+










-
+



-
-
+
+



-
-
+
+
+
+






-
-
+
+
+
+



+
+
+
-
+

+
+
-
+
-
-
+
+



+
+
+
-
+

+
+
-
+
-
-
+
+



+
+
+
-
+

+
+
-
+
-
-
+
+



+
+
+
-
+

+
+
-
+
-
-
+
+



-
+


-
-
+
+
+










-
+


-
-
+
+

+
-
-
+
+
-
-
+











-
+


-
-
+
+



-
-
+









-
+




-
+




-
-
+
+



-
+


-
-
+
+
+



-
+


-
-
+
+
+



-
+


-
-
+
+
+



-
+


-
+
+




-
+

+





-
+



-
+

+
+
-
+

-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










-
-
+
+
+
+
+
+
+
-
-
+
+
+
+

+










-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+

+












-
+






-





+
+
-
-
+
+

+










-
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+
+
+
+



-
+

-
+



-
+





-
-
-
-
+
+
+
+


-
+










-
-
-
-
+
+
+
+
+
+







-
+













+
+
-
-
+
+
+





-
+





-
-
-
+
+
+
+


-
+











+
+
-
-
-
+
+
+
+




















+
+
-
-
+
+
+



















-
+
+
+
+
+
+







-
+





-
+

-
+

-
+

-
+










-
+



-
+








-
+










-
+








-
+












-
+








-
+







    .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
    update
    lindex [.t bbox 1.5] 0
} 120
test textDisp-26.13 {AdjustForTab procedure, not enough space} {textfonts} {
test textDisp-26.13 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x
    set t1 [expr {   $fixedWidth+3}]
    set t2 [expr { 4*$fixedWidth+2}]
    set t3 [expr { 7*$fixedWidth+1}]
    set t4 [expr {17*$fixedWidth+1}]
    .t tag configure x -tabs {10 30 center 50 right 120}
    .t tag configure x -tabs "$t1 $t2 center $t3 right $t4"
    .t tag add x 1.0 end
    set expected [list [xchar 4] [xchar 8] [xchar 12] $t4]
    list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
	    [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]
} [list 28 56 84 120]
test textDisp-26.13.2 {AdjustForTab procedure, not enough space} {textfonts} {
    set res [list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
            [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]]
    lequal $res $expected
} {1}
test textDisp-26.13.2 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t insert 1.0 "abc\txyz\tqrs\txyz\t0"
    .t tag delete x
    set t1 [expr {   $fixedWidth+3}]
    set t2 [expr { 4*$fixedWidth+2}]
    set t3 [expr { 7*$fixedWidth+1}]
    set t4 [expr {17*$fixedWidth+1}]
    .t tag configure x -tabs {10 30 center 50 right 120} -tabstyle wordprocessor
    .t tag configure x -tabs "$t1 $t2 center $t3 right $t4" -tabstyle wordprocessor
    .t tag add x 1.0 end
    set expected [list [xchar 4] [xchar 8] $t4 [expr {$t4+($t4-$t3)}]]
    set res [list [lindex [.t bbox 1.4] 0] [lindex [.t bbox 1.8] 0] \
      [lindex [.t bbox 1.12] 0] [lindex [.t bbox 1.16] 0]]
    .t tag configure x -tabstyle tabular
    set res
} [list 28 56 120 190]
test textDisp-26.14 {AdjustForTab procedure, not enough space} {textfonts} {
    lequal $res $expected
} {1}
test textDisp-26.14 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t insert end "a \tb \tc \td \te \tf \tg\n"
    .t insert end "Watch the \tX and the \t\t\tY\n"
    .t tag configure moop -tabs [expr {8*$fixedWidth}]
    .t insert end "Watch the \tX and the \t\t\tY\n" moop
    list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \
	    [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]
} [list 77 224 77 224]
test textDisp-26.14.2 {AdjustForTab procedure, not enough space} {textfonts} {
} [list [xchar 11] [xchar 32] [xchar 11] [xchar 32]]
test textDisp-26.14.2 {AdjustForTab procedure, not enough space} {
    .t delete 1.0 end
    .t configure -tabstyle wordprocessor
    .t insert end "a \tb \tc \td \te \tf \tg\n"
    .t insert end "Watch the \tX and the \t\t\tY\n"
    .t tag configure moop -tabs [expr {8*$fixedWidth}]
    .t insert end "Watch the \tX and the \t\t\tY\n" moop
    set res [list [lindex [.t bbox 2.11] 0] [lindex [.t bbox 2.24] 0] \
      [lindex [.t bbox 3.11] 0] [lindex [.t bbox 3.24] 0]]
    .t configure -tabstyle tabular
    set res
} [list 112 56 112 56]
} [list [xchar 16] [xchar 8] [xchar 16] [xchar 8]]

.t configure -width 20 -bd 2 -highlightthickness 2 -relief sunken -tabs {} \
	-wrap char
updateText
test textDisp-27.1 {SizeOfTab procedure, old-style tabs} {textfonts} {
update
test textDisp-27.1 {SizeOfTab procedure, old-style tabs} {
    .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} {
} [list [list [xchar 8] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar [expr {8+8}]] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar [expr {8+8+1+1}]] [yline 1] $fixedWidth $fixedHeight]]
test textDisp-27.1.1 {SizeOfTab procedure, old-style tabs} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcdefghij\tc\td
    .t configure -tabstyle wordprocessor
    set res [list [.t bbox 1.2] [.t bbox 1.10] [.t bbox 1.12]]
    .t configure -tabstyle tabular
    set res
} [list [list 60 5 7 $fixedHeight] [list 116 5 7 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.2 {SizeOfTab procedure, choosing tabX and alignment} {textfonts} {
} [list [list [xchar 8] [yline 1] $fixedWidth $fixedHeight] \
        [list [xchar [expr {8+8}]] [yline 1] $fixedWidth $fixedHeight] \
	[list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.2 {SizeOfTab procedure, choosing tabX and alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\tbcd
    .t tag delete x
    # compute a tab width such that the first display line is just not large enough
    # to show the last char 'd', which then wraps on display line 2
    set tw [expr {(20-2)*$fixedWidth-($fixedWidth-1)}]
    .t tag configure x -tabs 120
    .t tag configure x -tabs $tw
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$tw+[xw 1]}] [yline 1] [expr {[winfo width .t]-([bo]+$tw+[xw 1])-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    list [.t bbox 1.3] [.t bbox 1.4]
    lequal [list [.t bbox 1.3] [.t bbox 1.4]] $expected
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.3 {SizeOfTab procedure, choosing tabX and alignment} {textfonts} {
} {1}
test textDisp-27.3 {SizeOfTab procedure, choosing tabX and alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t\t\tbcd
    .t tag delete x
    # compute a tab width such that the first display line is just not large enough
    # to show the last char 'd', which then wraps on display line 2
    set tw [expr {int(ceil(((20-2)*$fixedWidth-($fixedWidth-1))/3.0))}]
    .t tag configure x -tabs 40
    .t tag configure x -tabs $tw
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+3*$tw+[xw 1]}] [yline 1] [expr {[winfo width .t]-([bo]+3*$tw+[xw 1])-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    list [.t bbox 1.5] [.t bbox 1.6]
    lequal [list [.t bbox 1.5] [.t bbox 1.6]] $expected
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.4 {SizeOfTab procedure, choosing tabX and alignment} {textfonts} {
} {1}
test textDisp-27.4 {SizeOfTab procedure, choosing tabX and alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\t\t\tbcd
    .t tag delete x
    # compute a tab width such that the first display line is just not large enough
    # to show the last char 'd', which then wraps on display line 2
    set tw [expr {int(ceil(((20-2)*$fixedWidth-($fixedWidth-1) + 20)/2.0))}]
    .t tag configure x -tabs {20 center 70 left}
    .t tag configure x -tabs "20 center $tw left"
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$tw+($tw-20)+[xw 1]}] [yline 1] [expr {[winfo width .t]-([bo]+$tw+($tw-20)+[xw 1])-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    list [.t bbox 1.5] [.t bbox 1.6]
    lequal [list [.t bbox 1.5] [.t bbox 1.6]] $expected
} [list [list 131 5 13 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.5 {SizeOfTab procedure, center alignment} {textfonts} {
} {1}
test textDisp-27.5 {SizeOfTab procedure, center alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    # compute a tab width such that the last y on the first display line is the last displayed char
    # while 'xyzzyabc' is centered at the tab stop; the 'abc" part of the line wraps on display line 2
    set tw [expr {[winfo width .t]-2*[bo]-3*$fixedWidth+1}]
    .t tag configure x -tabs {120 center}
    .t tag configure x -tabs "$tw center"
    .t tag add x 1.0 end
    set expected [list [list [expr {[bo]+$tw+round(1.5*$fixedWidth)}] [yline 1] [expr {[winfo width .t]-([bo]+$tw+round(1.5*$fixedWidth))-[bo]}] $fixedHeight] \
                       [list [xchar 0] [yline 2] $fixedWidth $fixedHeight]]
    list [.t bbox 1.6] [.t bbox 1.7]
    lequal [list [.t bbox 1.6] [.t bbox 1.7]] $expected
} [list [list 135 5 9 $fixedHeight] [list 4 [expr {$fixedDiff + 18}] 7 $fixedHeight]]
test textDisp-27.6 {SizeOfTab procedure, center alignment} {textfonts} {
} {1}
test textDisp-27.6 {SizeOfTab procedure, center alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs {150 center}
    .t tag configure x -tabs "[expr {round(21.4*$fixedWidth)}] 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} {
} [list [list [xchar 4] [yline 2] $fixedWidth $fixedHeight] \
        [list [xchar 5] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.7 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {
    .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
    # more for 'bb\t' and we're there, with some pixels 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 tab [expr {[bo] + int(0.5 + $tab + $cm)}]
    update
    set res [.t bbox 2.23]
    set expected [list [expr {[xchar 23]-$tab}] [yline 2] $fixedWidth $fixedHeight]
    lset res 0 [expr {[lindex $res 0] - $tab}]
    set res
    lequal [lset res 0 [expr {[lindex $res 0] - $tab}]] $expected
} {1}
} [list -28 [expr {$fixedDiff + 18}] 7 $fixedHeight]
test textDisp-27.7.1 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {textfonts} {
test textDisp-27.7.1 {SizeOfTab procedure, center alignment, wrap -none (potential numerical problems)} {
    .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
    # more for 'bb\t' and we're there, with some pixels 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 tab [expr {[bo] + 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]
} [list 0 [yline 2] $fixedWidth $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
    update
    set res [.t bbox 1.20]
    # Now, Tk's interpolated tabs should be the same as
    # non-interpolated.
    .t configure -tabs $precisetab
    updateText
    update
    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} {
update
test textDisp-27.8 {SizeOfTab procedure, right alignment} {
    .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 configure x -tabs "[expr {14.3*$fixedWidth}] left [expr {[.t cget -width]*$fixedWidth}] 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} {
} [list [list [xcharr 1] [yline 1] $fixedWidth $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.9 {SizeOfTab procedure, left alignment} {
    .t delete 1.0 end
    .t insert 1.0 a\txyzzyabc
    .t tag delete x
    .t tag configure x -tabs 120
    .t tag configure x -tabs "[expr {17.14*$fixedWidth}]"
    .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} {
} [list [list [expr {round([bo]+17.14*$fixedWidth+$fixedWidth)}] [yline 1] [expr {[winfo width .t]-round([bo]+17.14*$fixedWidth+$fixedWidth)-[bo]}] $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.10 {SizeOfTab procedure, numeric alignment} {
    .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 configure x -tabs "[expr {17.14*$fixedWidth}] 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} {
} [list [list [expr {round([bo]+17.14*$fixedWidth-$fixedWidth)}] [yline 1] [expr {[winfo width .t]-round([bo]+17.14*$fixedWidth-$fixedWidth)-[bo]}] $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]
test textDisp-27.11 {SizeOfTab procedure, making tabs at least as wide as a space} {
    .t delete 1.0 end
    .t insert 1.0 abc\tdefghijklmnopqrst
    .t tag delete x
    .t tag configure x -tabs 120
    .t tag configure x -tabs "[expr {17.14*$fixedWidth}]"
    .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]]
} [list [list [expr {round([bo]+17.14*$fixedWidth+$fixedWidth)}] [yline 1] [expr {[winfo width .t]-round([bo]+17.14*$fixedWidth+$fixedWidth)-[bo]}] $fixedHeight] \
        [list [bo] [yline 2] $fixedWidth $fixedHeight]]

proc bizarre_scroll args {
    .t2.t delete 5.0 end
}
test textDisp-28.1 {"yview" option with bizarre scroll command} {
test textDisp-28.1 {"yview" option with bizarre scroll command} -setup {
    catch {destroy .t2}
} -body {
    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
    update
    .t2.t configure -yscrollcommand bizarre_scroll
    .t2.t yview 100.0
    set result [.t2.t index @0,0]
    updateText
    update
    lappend result [.t2.t index @0,0]
} -cleanup {
    destroy .t2
} {6.0 1.0}
} -result {6.0 1.0}

test textDisp-29.1 {miscellaneous: lines wrap but are still too long} {textfonts} {
test textDisp-29.1 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    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
    set expected [list [list 0.0 [expr {20.0*$fixedWidth/300}]] \
                       300x50+[bo .t2.t]+[yline 2 .t2.t] \
	               [list [xchar 1 .t2.t] [expr {[yline 2 .t2.t]+50}] $fixedWidth $fixedHeight]]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    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
    set expected [list [list [expr {1.0*$fixedWidth/300}] [expr {21.0*$fixedWidth/300}]] \
                       300x50+[expr {[bo .t2.t]-$fixedWidth}]+[yline 2 .t2.t] \
	               [list [expr {[bo .t2.t]-$fixedWidth+$fixedWidth}] [expr {[yline 2 .t2.t]+50}] $fixedWidth $fixedHeight]]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2.1 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    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
} -cleanup {
    destroy .t2
} -result [list [expr {5.0/90}] [expr {25.0/90}]]
test textDisp-29.2.2 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    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
    set expected [list [list [expr {2.0*$fixedWidth/300}] [expr {22.0*$fixedWidth/300}]] \
                       300x50+[expr {[bo .t2.t]-2*$fixedWidth}]+[yline 2 .t2.t] \
	               {}]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2.3 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    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]
    update
    .t2.t xview scroll 7 pixels
    update
    set expected [list [list [expr {7.0/300}] [expr {(20.0*$fixedWidth+7)/300}]] \
                       300x50+[expr {[bo .t2.t]-7}]+[yline 2 .t2.t] \
	               [list [expr {[bo .t2.t]+$fixedWidth-7}] [expr {[yline 2 .t2.t]+50}] $fixedWidth $fixedHeight]]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} [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} {
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-29.2.4 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    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
    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 {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}]]
    set expected [list [list [expr {17.0/300}] [expr {(20.0*$fixedWidth+17)/300}]] \
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
                       300x50+[expr {[bo .t2.t]-17}]+[yline 2 .t2.t] \
    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]
	               {}]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} [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
} -cleanup {
    .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}
    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
} -result {1}
    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} {
test textDisp-29.2.5 {miscellaneous: can show last character} -setup {
    catch {destroy .t2}
} -body {
    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
    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]

    if {($iWidth == $iWidth2) && $iWidth >= 2} {
	set result "correct"
    } else {
	set result "last character is not completely visible when it should be"
    }
} -cleanup {
    destroy .t2
} {correct}
test textDisp-29.3 {miscellaneous: lines wrap but are still too long} {textfonts} {
} -result {correct}
test textDisp-29.3 {miscellaneous: lines wrap but are still too long} -setup {
    catch {destroy .t2}
} -body {
    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
    update
    .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} {
    update
    set expected [list [list [expr {double(300-20*$fixedWidth)/300}] 1.0] \
                       300x50+[expr {-(300-20*$fixedWidth-[bo .t2.t])}]+[yline 2 .t2.t] \
	               {}]
    lequal [list [.t2.t xview] [winfo geom .t2.t.f] [.t2.t bbox 1.3]] $expected
} -cleanup {
    destroy .t2
} -result {1}

test textDisp-30.1 {elided text joining multiple logical lines} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    text .t2.t -width 20 -height 10 -font $fixedFont
    pack .t2.t -side top
    .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 tag configure elided -elide 1 -background red
    .t2.t tag add elided 1.2 3.2
    update
    .t2.t count -update -displaylines 1.0 end
} -cleanup {
    destroy .t2
} -result {1}
test textDisp-30.2 {elided text joining multiple logical lines} -setup {
    catch {destroy .t2}
} -body {
    toplevel .t2
    text .t2.t -width 20 -height 10 -font $fixedFont
    pack .t2.t -side top
    .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
    .t2.t tag configure elided -elide 1 -background red
    .t2.t tag add elided 1.2 2.2
    update
    .t2.t count -update -displaylines 1.0 end
} -cleanup {
    destroy .t2
} -result {2}
catch {destroy .t2}

.t configure -height 1
updateText
update

test textDisp-31.1 {line embedded window height update} failsOnUbuntu {
test textDisp-31.1 {line embedded window height update} {
    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
    frame .t.f -background red -width 50 -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 {
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*6}] \
	[expr {$fixedHeight*7}]]
test textDisp-31.2 {line update index shifting} {
    set res {}
    .t.f configure -height 100
    updateText
    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
    .t delete 1.0 3.0
    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 * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.3 {line update index shifting} failsOnUbuntu {
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*8}] \
	[expr {$fixedHeight*9}] \
	[expr {$fixedHeight*7}] \
	[expr {100+$fixedHeight*6}]]
test textDisp-31.3 {line update index shifting} {
    # 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
    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]
    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}] \
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

	[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
    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 {
} [list [expr {100+$fixedHeight*6}] \
        [expr {100+$fixedHeight*6}] \
	[expr {$fixedHeight*7}]]
test textDisp-31.5 {line update index shifting} {
    set res {}
    textest configure -height 100
    updateText
    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
    .t delete 1.0 3.0
    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*8}] \
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

test textDisp-31.6 {line update index shifting} failsOnUbuntu {
	[expr {$fixedHeight*9}] \
	[expr {$fixedHeight*7}] \
	[expr {100+$fixedHeight*6}]]
test textDisp-31.6 {line update index shifting} {
    # 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}] \
} [list [expr {100 + $fixedHeight * 6}] [expr {100 + $fixedHeight * 8}] [expr {$fixedHeight * 9}] [expr {$fixedHeight * 7}] [expr {100 + $fixedHeight * 6}]]

	[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}]]
} [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
    update
    destroy .tt
} {}
test textDisp-32.1 {everything elided} {
    # Must not crash
    pack [text .tt]
    updateText
    update
    .tt insert 0.0 HELLO
    updateText
    update
    .tt tag configure HIDE -elide 1
    updateText
    update
    .tt tag add HIDE 0.0 end
    updateText
    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}
    updateText
    update
    # indent left margin of tag 1 by 20 pixels
    # text should be indented
    .tt tag configure testtag1 -lmargin1 20
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    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
    updateText
    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
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269

4270
4271
4272
4273
4274
4275
4276
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







-
+




+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+

-
+






-
+

-
+

+










-
+










-


-
-
+
+
-

-





-
-

-
+








-












-
+







    .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
    update
} -cleanup {
    image delete $img
    destroy .tt
}
test textDisp-32.4 {Button-1 click with elided lines - Bug 18371b7ce7} -setup {
    pack [text .tt -borderwidth 0 -highlightthickness 0]
    for {set n 1} {$n <= 5} {incr n} {
	.tt insert end "Line $n\n"
    }
    .tt tag configure Elided -elide 1
    .tt tag add Elided 1.2 4.0
    update
} -body {
    event generate .tt <Button-1> -x 1 -y 1
    .tt index insert
} -cleanup {
    destroy .tt
} -result {1.0}

test textDisp-33.0 {one line longer than fits in the widget} {
    pack [text .tt -wrap char]
    updateText
    update
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    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]
    updateText
    update
    .tt insert 1.0 [string repeat "more wrap + " 300]
    updateText
    update
    .tt yview "1.0 +1 displaylines"
    update
    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
    update
    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
    update
    .tt sync
    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
    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"
    }
    set idx [.tt index "1.0 + 1 displaylines"]
    .tt debug 0
    set result
} {ok}
destroy .tt
test textDisp-33.5 {bold or italic fonts} win {
    destroy .tt
    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
    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)} {
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
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







-


-
+









-
+








+
+
+
+
+











+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    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
    update
    .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
    update
    .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
    # We don't want debug for this test case, because it takes some hours
    # if valgrind check is fully enabled. In this test case only the scrollbar
    # behavior is relevant, all other involved functions (insert, see, ...) are
    # already tested with debug mode in other test cases.
    .t debug off
    .t insert end "[string repeat a\nb\nc\n 500000]THE END\n"
    set res {}
} -body {
    .t see 10000.0
    after 300 {set fr1 [.t yview] ; set done 1}
    vwait done
    after 300 {set fr2 [.t yview] ; set done 1}
    vwait done
    lappend res [expr {[lindex $fr1 0] == [lindex $fr2 0]}]
    lappend res [expr {[lindex $fr1 1] == [lindex $fr2 1]}]
} -cleanup {
    .t debug on ;# re-enable debugging
    destroy .t1
} -result {1 1}

test textDisp-36.1 {Display bug with 'yview insert'} -constraints {knownBug} -setup {
   text .t1 -font $fixedFont -width 20 -height 3 -wrap word
   pack .t1
   .t1 delete 1.0 end
   .t1 tag configure elide -elide 1
   .t1 insert end "Line 1\nThis line is wrapping around two times."
} -body {
   .t1 tag add elide 1.3 2.0
   .t1 yview insert
   update
   # wish now panics: "CalculateDisplayLineHeight called with bad indexPtr"
   .t1 yview scroll -1 pixels
} -cleanup {
    destroy .t1
} -result {}

deleteWindows
option clear

# cleanup
cleanupTests
return
Changes to tests/textImage.test.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







# 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.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands
imageInit
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278







-
+







    .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}
} -result {small small#1 small#2 small#6342}

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
382
383
384
385
386
387
388

389
390
391
392
393
394
395
396
397
398








399
400

401
402
403
404
405
406
407
382
383
384
385
386
387
388
389
390
391
392







393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







+



-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
+







    }
    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
    update
    # 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)
        font configure test_font2 -size $size
        array set Metrics [font metrics test_font2]
        update  ; # services the idle "TheWorldHasChanged" event, queues "TkWorldChanged" events
        update  ; # services the queued "TkWorldChanged" events
        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"
        lappend result "$size $norm"
    }
    return $result
} -cleanup {
    destroy .t
    image delete small large
    font delete test_font2
    unset Metrics
Changes to tests/textIndex.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+







wm positionfrom . user
wm deiconify .

.t insert 1.0 "Line 1
abcdefghijklm
12345
Line 4
by GIrl .#@? x_yz
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
114
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).
    # 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
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).
    # 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)

264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278







-
+







test textIndex-4.8 {TkTextGetIndex, tags} {
    .t tag add z 1.0
    set result [list [.t index z.first] [.t index z.last]]
    .t tag delete z
    set result
} {1.0 1.1}

test textIndex-5.1 {TkTextGetIndex, "@"} {nonPortable fonts} {
test textIndex-5.1 {TkTextGetIndex, "@"} {fonts} {
    .t index @12,9
} 1.1
test textIndex-5.2 {TkTextGetIndex, "@"} {fonts} {
    .t index @-2,7
} 1.0
test textIndex-5.3 {TkTextGetIndex, "@"} {fonts} {
    .t index @10,-7
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
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"]
}
750
751
752
753
754
755
756

757
758
759
760
761
762
763
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764







+







}

set str [string repeat "hello " 20]

.t insert end "$str one two three four five six seven height nine ten\n"
.t insert end "$str one two three four five six seven height nine ten\n"
.t insert end "$str one two three four five six seven height nine ten\n"
update

test textIndex-19.1 {Display lines} {
    .t index "2.7 displaylinestart"
} {2.0}

test textIndex-19.2 {Display lines} {
    .t index "2.7 displaylineend"
829
830
831
832
833
834
835












836
837
838
839
840
841
842
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







+
+
+
+
+
+
+
+
+
+
+
+







    .txt insert HISTORY "\n" {NICK NICK-tick}
    .txt insert HISTORY {[23:51]	} STAMP
    .txt insert HISTORY "\n" {NICK NICK-tick}
    # Must not crash
    .txt index "2.0 - 2 display lines"
    destroy .txt .sbar
} {}

test textIndex-19.14 {Display lines with elided lines} {
    catch {destroy .t}
    pack [text .t]
    for {set n 1} {$n <= 1000} {incr n} {
	.t insert end "Line $n\n"
    }
    .t tag configure Elided -elide 1
    .t tag add Elided 6.0 951.0
    update
    set res [.t index "951.0 + 1 displaylines"]
} {952.0}

proc text_test_word {startend chars start} {
    destroy .t
    text .t
    .t insert end $chars
    if {[regexp {end} $start]} {
	set start [.t index "${start}chars -2c"]
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
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







-
+


-
+


-
+


-
+


-
+







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
    text_test_word wordend "xyz\u00c7de fg" 0
} 6
test textIndex-21.11 {text index wordend, unicode} {
    text_test_word wordend "xyzde fg" 0
    text_test_word wordend "xyz\uc700de fg" 0
} 6
test textIndex-21.12 {text index wordend, unicode} {
    text_test_word wordend "xyzde fg" 0
    text_test_word wordend "xyz\u203fde fg" 0
} 6
test textIndex-21.13 {text index wordend, unicode} {
    text_test_word wordend "xyzde fg" 0
    text_test_word wordend "xyz\u2045de fg" 0
} 3
test textIndex-21.14 {text index wordend, unicode} {
    text_test_word wordend "윀윀 abc" 8
    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
928
929
930










931
932
933
934
935
936
937
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







-
+


-
+


-
+




-
-
+
+










+
+
+
+
+
+
+
+
+
+







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
    text_test_word wordstart "one tw\u00c7o three" 7
} 4
test textIndex-22.12 {text index wordstart, unicode} {
    text_test_word wordstart "ab윀윀 cdef ghi" 12
    text_test_word wordstart "ab\uc700\uc700 cdef ghi" 12
} 10
test textIndex-22.13 {text index wordstart, unicode} {
    text_test_word wordstart "윀윀 abc" 8
    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çais\n"
    .t insert end "Это текст на русском"
    .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}
    text .t
    .t index "1.0 display wordstart"  ; # used to crash
} 1.0
test textIndex-22.16 {text index wordstart, bug [57b821d2db]} {
    catch {destroy .t}
    text .t
    .t insert 1.0 " 123 5 789012  LINE-1\n\n 123 5 789000 LINE-3\n\n0123 5 789012  LINE-5"
    set res [.t index "1.1 wordstart"]
    lappend res [.t index "5.0 wordstart"]
    .t mark set insert 1.1
    lappend res [.t index "insert wordstart"]
    lappend res [.t index "5.1 wordstart"]
} {1.1 5.0 1.1 5.0}

test textIndex-23.1 {text paragraph start} {
    pack [text .t2]
    .t2 insert end " Text"
    set res 2.0
    for {set i 0} {$i < 2} {incr i} {
	lappend res [::tk::TextPrevPara .t2 [lindex $res end]]
959
960
961
962
963
964
965





































966
967
968
969
970
971
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






    .t2 insert end "21\n22\n23\n25\n26\n27\n28\n29\n30\n31"
    .t2 insert end "32\n33\n34\n36\n37\n38\n39" elided
    # then this used to crash Tk:
    .t2 see end
    focus -force .t2   ; # to see the cursor blink
    destroy .t2
} {}

test textIndex-26.1 {GetIndex restricts the returned index to -startline/-endline in peers, bug [34db75c0ac]} {
    set res {}
    pack [text .t2]
    .t2 insert end "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\n"
    pack [.t2 peer create .p2 -startline 2 -endline 3]
    lappend res [.p2 index "end"]
    lappend res [.p2 index "end lineend"]
    lappend res [.p2 index "end display lineend"]
    destroy .t2 .p2
    set res
} {2.0 2.0 2.0}
test textIndex-26.2 {GetIndex errors out if mark, image, window, or tag is outside peer -startline/-endline, bug [34db75c0ac]} {
    set res {}
    pack [text .t2]
    .t2 insert end "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\n"
    pack [.t2 peer create .p2 -startline 2 -endline 3]
    .p2 configure -startline 3 -endline {}
    .t2 mark set mymark 1.0
    catch {.p2 index mymark} msg
    lappend res [.t2 index mymark] $msg
    image create photo redsquare -width 5 -height 5
    redsquare put red -to 0 0 4 4
    .t2 image create 1.0 -image redsquare
    catch {.p2 index redsquare} msg
    lappend res [.t2 index redsquare] $msg
    frame .f -width 10 -height 10 -bg blue
    .t2 window create 1.2 -window .f
    catch {.p2 index .f} msg
    lappend res [.t2 index .f] $msg
    .t2 tag add mytag 1.3
    catch {.p2 index mytag.first} msg
    lappend res [.t2 index mytag.first] $msg
    destroy .t2 .p2
    set res
} {1.0 {bad text index "mymark"} 1.0 {bad text index "redsquare"} 1.2\
   {bad text index ".f"} 1.3 {text doesn't contain any characters tagged with "mytag"}}

# cleanup
rename textimage {}
catch {destroy .t}
cleanupTests
return
Changes to tests/textMark.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

178
179
180
181
182
183
184











185
186
187
188
189
190
191
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202







+
+
+
+
+
+
+
+
+
+
+







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-6.6 {attempt to move the insert mark beyond peer -endline - bug 34db75c0ac} -body {
  .t peer create .p -startline 1 -endline 2
  pack .p
  update
  .p mark set insert 1.2
  focus -force .p
  event generate .p <<NextLine>>  ; # shall not error out
  set res [.p index insert]
} -cleanup {
  destroy .p
} -result {1.9}

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
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
1
2
3



4
5
6
7
8
9
10
11
12
13


14
15
16










17
18
19


20
21
22


23
24

25
26
27
28
29
30
31
32



-
-
-
+
+
+







-
-
+
+

-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
+
-
-


-
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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}
set fixedFont {Courier 12}
set bigFont   {Helvetica 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 }
# Warn the user if the actual font is too different from what was requested.
if {[font metrics [font actual $fixedFont] -fixed] != 1} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
]

does not seem to be a fixed-width font as expected. If this is really the case, many upcoming\
tests will fail."
}
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
text .t -width 20 -height 10 -font $fixedFont

pack .t -expand 1 -fill both
update
.t debug on

wm geometry . {}

77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83







-
+







    .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
} -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
117
118
119
120
121
122
123
124
125




126
127
128

129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
109
110
111
112
113
114
115


116
117
118
119
120
121

122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
-
+
+
+
+


-
+





-
+










-
+







} -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
test textTag-1.13 {configuration options, bug [026e2bb685]} -body {
    .t tag configure x -justify right
    catch {.t tag configure x -justify middle} msg
    list $msg [.t tag configure x -justify]
} -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}
} -result {{bad justification "middle": must be left, right, or center} {-justify {} {} {} right}}
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
} -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
} -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
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168







-
+







    .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
} -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
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212







-
+







    .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
} -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
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268




269
270
271


272
273
274
275
276
277

278
279
280
281
282
283
284
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259



260
261
262
263
264


265
266
267
268
269
270
271

272
273
274
275
276
277
278
279







-
+










-
-
-
+
+
+
+

-
-
+
+





-
+







    .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
} -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
} -result {10}
test textTag-1.29 {configuration options, bug [026e2bb685]} -body {
    catch {.t tag configure x -spacing3 5 -spacing2 bad -spacing1 morebad} msg
    list $msg [.t tag configure x -spacing1] [.t tag configure x -spacing2] [.t tag configure x -spacing3]
} -cleanup {
    .t tag configure x -spacing2 [lindex [.t tag configure x -spacing2] 3]
} -returnCodes error -result {bad screen distance "bad"}
    .t tag configure x -spacing1 [lindex [.t tag configure x -spacing1] 3] -spacing2 [lindex [.t tag configure x -spacing2] 3] -spacing3 [lindex [.t tag configure x -spacing3] 3]
} -result {{bad screen distance "bad"} {-spacing1 {} {} {} {}} {-spacing2 {} {} {} {}} {-spacing3 {} {} {} 5}}
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
} -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}
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405

406
407
408
409
410
411
412
386
387
388
389
390
391
392

393
394
395
396
397
398
399

400
401
402
403
404
405
406
407







-
+






-
+







    .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 tag configure mytag -offset 2
    .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
} -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
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501
482
483
484
485
486
487
488

489
490
491
492
493
494
495
496







-
+







} -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 ...?"}
} -returnCodes error -result {wrong # args: should be ".t tag configure tagName ?-option? ?value? ?-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
542
543
544
545
546
547
548
549

550
551


552
553
554

555
556
557
558
559
560
561
537
538
539
540
541
542
543

544
545

546
547
548
549

550
551
552
553
554
555
556
557







-
+

-
+
+


-
+







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 {
test textTag-5.9 {TkTextTagCmd - "configure" option, bug [026e2bb685]} -body {
    .t tag delete x
    .t tag configure x -justify bogus
    catch {.t tag configure x -justify bogus} msg
    list $msg [.t tag configure x -justify]
} -cleanup {
    .t tag delete x
} -returnCodes error -result {bad justification "bogus": must be left, right, or center}
} -result {{bad justification "bogus": must be left, right, or center} {-justify {} {} {} {}}}
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 {
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
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







-
-
-









-
-
-
-
-
-
-
-
-




-
+
+







        .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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -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
1259
1260
1261
1262
1263
1264
1265
1266


1267
1268
1269

1270
1271
1272
1273

1274
1275
1276
1277
1278
1279
1280
1244
1245
1246
1247
1248
1249
1250

1251
1252
1253
1254

1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
1266







-
+
+


-
+



-
+







    .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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag bind x <Enter> {lappend x x-enter}
    .t tag bind x <Button> {lappend x x-down}
    .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 <Button> {lappend x y-down}
    .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
1288
1289
1290
1291
1292
1293
1294
1295


1296
1297
1298
1299


1300
1301
1302
1303


1304
1305
1306
1307
1308
1309
1310
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284


1285
1286
1287
1288


1289
1290
1291
1292
1293
1294
1295
1296
1297







-
+
+


-
-
+
+


-
-
+
+







} -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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -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 <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 <Button-1> {lappend x y-down}
    .t tag bind y <ButtonRelease-1> {lappend x y-up}
    .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 |
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+
+


















-
+



-
-
+
+


+
+
-
-
+
+






-







-
+
+







    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-15.4 {TkTextBindProc, key event with mouse outside the widget} -setup {
    .t tag delete {*}[.t tag names]
    wm geometry . +200+200 ; update
} -body {
    set res {}
    .t tag add tag1 1.0 end
    .t tag bind tag1 <KeyPress> {lappend res %K}
    .t mark set insert 1.2
    update
    event generate .t <Motion> -warp 1 -x -50 -y -50
    controlPointerWarpTiming
    focus -force .t
    event generate .t <KeyPress> -keysym a
    set res
} -cleanup {
    .t tag delete tag1
} -result {a}


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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -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
    haveBigFontTwiceLargerThanTextFont
} -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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag configure big -font $bigFont
    # update needed here to stabilize the test
    update
    event gen .t <ButtonRelease-1> -state 0x100 -x $x4 -y $y4
    event gen .t <Motion> -x $x5 -y $y5
    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]
} -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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -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
1393
1394
1395
1396
1397
1398
1399
1400


1401
1402
1403
1404
1405
1406
1407
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
1415
1416







-
+
+







} -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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -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
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
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







-
+
-
-




-
+
-
+


-
+


-
+



-



-
+





-
-
+
+


-
+


-
+




-



-
+





-
-
+
+





-
+


-
+




-

















-
+
+
















+
+
+
+






-
+









    .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 {
test textTag-16.5 {TkTextPickCurrent procedure} -setup {
    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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    .t configure -font $textWidgetFont -wrap none
    controlPointerWarpTiming
} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x4 -y $y4
    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 $x5 -y $y5
    event gen .t <Motion> -x $x2 -y $y2
    .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
    haveBigFontTwiceLargerThanTextFont
} -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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    .t tag configure big -font $bigFont
    event gen .t <Motion> -x $x4 -y $y4
    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 $x5 -y $y5
    event gen .t <Motion> -x $x2 -y $y2
    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
    haveBigFontTwiceLargerThanTextFont
} -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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -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
    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 $x5 -y $y5
    event gen .t <Motion> -x $x2 -y $y2
    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
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    text .t -width 30 -height 4 -relief sunken -borderwidth 10 \
      -highlightthickness 10 -pady 2
    pack .t
    update ; # map the window, otherwise -warp can't be done

    .t insert end " Tag here " TAG " no tag here"
    .t tag configure TAG -borderwidth 4 -relief raised
    .t tag bind TAG <Enter>  {lappend res "%x %y tag-Enter"}
    .t tag bind TAG <Leave>  {lappend res "%x %y tag-Leave"}
    bind .t <Enter> {lappend res Enter}
    bind .t <Leave> {lappend res Leave}

    set res {}
    # Bindings must not trigger on the widget border, only over
    # the actual tagged characters themselves.
    # Note that we don't need to call controlPointerWarpTiming
    # in the following six calls because we're not checking that
    # the mouse pointer has actually moved but rather that the
    # tag binding mechanism of the text widget correctly triggers.
    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
    set res
} -cleanup {
    destroy .t
} -result {Enter {25 25 tag-Enter} {20 20 tag-Leave} {25 25 tag-Enter}}

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
1
2
3



4
5
6
7
8
9
10
11
12
13


14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39




40
41
42
43
44
45
46
47
48
49
50



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







88
89
90
91
92
93
94
95
96
97
98
99
100
101


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126



-
-
-
+
+
+







-
-


-
+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+
+
+




+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+














-
-
-
-
-
-
-














-
-
+
+














-
-
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 fixedFont {Courier -12}
set fixedHeight [font metrics $fixedFont -linespace]
set fixedWidth [font measure $fixedFont m]
set fixedAscent [font metrics $fixedFont -ascent]

# On Windows at least, the tests do work with {Courier -10}, {Courier -12} or {Courier -14} as fixedFont.
# Warn the user if the actual font is too different from what was requested.
if {[font metrics [font actual $fixedFont] -fixed] != 1} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
does not seem to be a fixed-width font as expected. If this is really the case, many upcoming\
tests will fail."
}
if {$fixedHeight < 12 || $fixedHeight > 17} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedHeight pixels height while the tests expect between 12 and 17 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}
if {$fixedWidth < 6 || $fixedWidth > 8} {
    puts "---> Warning: the font actually used by the tests, which is \"[font actual $fixedFont]\",\
is $fixedWidth pixels in width while the tests expect between 6 and 8 (inclusive) pixels.\
Some of the upcoming tests will probably fail."
}

# Widget used in almost all tests
set tWidth 30
set tHeight 6
text .t -width $tWidth -height $tHeight -bd 2 -highlightthickness 2 \
        -font $fixedFont
# Option  -width 30  (characters) below is a fundamental assumption of many
# upcoming tests when wrapping enters in play
# Also  -height 6  (lines) is an important assumption
# Moreover the widget must have the same padding in x and y (see proc bo)
# However the tests are not sensitive to  -borderwidth  and  -highlightthickness
text .t -font $fixedFont -width 30 -height 6 -borderwidth 2 -highlightthickness 2
pack .t -expand 1 -fill both
update
.t debug on

wm geometry . {}
set color [expr {[winfo depth .t] > 1 ? "green" : "black"}]

wm geometry . {}

# full border size of the text widget, i.e. first x or y coordinate inside the text widget
# warning:  -padx  is supposed to be the same as  -pady  (same border size horizontally and
# vertically around the widget)
proc bo {{w .t}} {
    return [expr {[$w cget -borderwidth] + [$w cget -highlightthickness] + [$w cget -padx]}]
}
# x-width of $n chars, fixed width font
proc xw {n} {
    global fixedWidth
    return [expr {$n * $fixedWidth}]
}
# x-coordinate of the first pixel of $n-th char (count starts at zero), left justified
proc xchar {n {w .t}} {
    return [expr {[bo $w] + [xw $n]}]
}
# y-coordinate of the first pixel of $l-th display line (count starts at 1)
proc yline {l {w .t}} {
    global fixedHeight
    return [expr {[bo $w] + ($l - 1) * $fixedHeight}]
}

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 .

# 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] \
    3x3+[xchar 2]+[expr {[yline 2]+($fixedHeight-3)/2}] \
    [list [xchar 2] [expr {[yline 2]+($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] \
    3x3+[xchar 2]+[yline 2] \
    [list [xchar 2] [yline 2] 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"
103
104
105
106
107
108
109
110

111
112

113
114
115
116
117
118
119
120
121
122
123
124

125
126

127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
135
136
137
138
139
140
141

142
143

144
145
146
147
148
149
150
151
152
153
154
155

156
157

158
159
160
161
162
163
164
165
166
167
168
169

170
171

172
173
174
175
176
177
178







-
+

-
+











-
+

-
+











-
+

-







    .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}] \
    10x20+[expr {[xchar 2]+5}]+[yline 2] \
    {-padx {} {} 0 5} \
    [list [expr {$padx+2*$fixedWidth+10+2*5}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]
    [list [expr {[xchar 2]+10+2*5}] [expr {[yline 2]+(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}] \
    10x20+[xchar 2]+[expr {[yline 2]+4}] \
    {-pady {} {} 0 4} \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+20+2*4}] $fixedWidth $fixedHeight]]
    [list [xchar 2] [expr {[yline 2]+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}] \
    5x$fixedHeight+[xchar 2]+[yline 2] \
    {-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 {
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256







-















-







    .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"
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307







-
















-









-







} -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}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
347
348
349
350
351
352
353

354
355
356
357
358
359
360







-







        .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 {
353
354
355
356
357
358
359

360
361
362
363

364
365
366
367


368
369
370
371
372
373
374
378
379
380
381
382
383
384
385
386
387


388
389
390


391
392
393
394
395
396
397
398
399







+


-
-
+


-
-
+
+







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
    set res [winfo ismapped .f]
    .t window configure 1.3 -window {}
    update
    catch {.t index .f}
    list [winfo ismapped .f] [.t bbox 1.4]
    lappend res [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]
} -result [list 1 0 \
    [list [xchar 3] [yline 1] $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
383
384
385
386
387
388
389

390
391
392
393

394
395
396
397


398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452

453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
408
409
410
411
412
413
414
415
416
417


418
419
420


421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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







+


-
-
+


-
-
+
+














-
+












+










+











+







+













-



+







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
    set res [winfo ismapped .t.f]
    .t window configure 1.3 -window {}
    update
    catch {.t index .t.f}
    list [winfo ismapped .t.f] [.t bbox 1.4]
    lappend res [winfo ismapped .t.f] [.t bbox 1.4]
} -cleanup {
    destroy .t.f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]
} -result [list 1 0 \
    [list [xchar 3] [yline 1] $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]]
    [list [expr {[xchar 3]+10}] [expr {[yline 1]+(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
513
514
515
516
517
518
519
520
521


522
523
524
525
526
527
528
542
543
544
545
546
547
548


549
550
551
552
553
554
555
556
557







-
-
+
+







    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]]
    [list [xchar 2] [expr {[yline 1]+$fixedHeight/2}] 0 0] \
    [list [xchar 2] [yline 1] $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
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
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







-
-
+
+













-
-
+
+
-















-
-
-
+
+
+
-
-
+















-
-
+
+















-
-
+
+













-
-
+
+















-












-







    .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]]
    [list [xchar 2] [yline 2] 0 0] \
    [list [xchar 2] [yline 1] $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]]
    [list [xchar 2] [expr {[yline 1]+($fixedHeight-10)/2}] 20 10] \
    [list [expr {[xchar 2]+20}] [yline 1] $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 [xchar 2] [yline 1] 10 20] \
    [list [expr {[xchar 2]+10}] [expr {[yline 1]+(20-$fixedHeight)/2}] $fixedWidth $fixedHeight] \
    [list [xchar 2] [yline 1] 25 30] \
    [list [expr {$padx+2*$fixedWidth+25}] [expr {$pady+((30-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

    [list [expr {[xchar 2]+25}] [expr {[yline 1]+(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]]
    10x20+[expr {[bo]+100}]+[expr {[bo]+50}] \
    [list [xchar 2] [expr {[yline 1]+$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]]
    10x20+[expr {[bo]+100}]+[expr {[bo]+50}] \
    [list [xchar 2] [expr {[yline 1]+$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] \
    [list [xchar 2] [yline 1] $fixedWidth $fixedHeight] \
    [list [xchar 3] [yline 1] $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 {
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
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







-
+



















-
+







    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]]
    [list [xchar 5] [expr {[yline 1]+$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]]
    [list [xchar 5] [expr {[yline 1]+$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
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
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







-
+


















-
+







    }
    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] \
    [list [xchar 5] [expr {[yline 1]+$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
    update
    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 {
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
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







-
+

-
+














-
+





-
+







    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]]
    [list [xchar 5] [expr {[yline 1]+$fixedHeight/2}] 0 0]]

test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -constraints failsOnUbuntu -setup {
test textWind-10.7 {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
    update idletasks ; after 100 ; 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]]
    [list [xchar 5] [expr {[yline 1]+$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
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
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







-
+





-
-
+
+







-
+






-
-
+
+







-
+






-
-
+
+







-
+






-
+








-
+






-
+















-
+







-
+





+


-
+




-
+






-
+





+


-
+





-
+






-
+








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
    frame .f -width [expr {([.t cget -width]-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]]
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] 20] \
    [list [xchar 0] [expr {[yline 1]+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
    frame .f -width [expr {([.t cget -width]-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]]
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] 20] \
    [list [xchar 0] [expr {[yline 1]+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
    frame .f -width [expr {([.t cget -width]-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]]
    [list [xchar 0] [yline 2] [expr {[xw [expr {[.t cget -width]-12}]]+1}] 20] \
    [list [expr {[xchar 0]+[expr {[xw [expr {[.t cget -width]-12}]]+1}]}] [expr {[yline 2]+(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
    frame .f -width [expr {([.t cget -width]-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] \
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] 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
    frame .f -width [expr {([.t cget -width]-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}]] \
    [list [xchar 12] [yline 1] [xw [expr {[.t cget -width]-12}]] [expr {[.t cget -height]*$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}]] \
    [list [xchar 0] [yline 2] [xw [.t cget -width]] [expr {([.t cget -height]-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
    # 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
    update
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update ; after 100 ; update
    update
    winfo geom .f
} -cleanup {
    destroy .f
    place forget .t
} -result [list 30x20+[expr {$padx+30+12*$fixedWidth}]+[expr {$pady+50}]]
} -result [list 30x20+[expr {[xchar 12]+30}]+[expr {[yline 1]+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
    # 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
    update
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .t.f
    update ; after 100 ; update
    update
    winfo geom .t.f
} -cleanup {
    destroy .t.f
    place forget .t
    pack .t
} -result [list 30x20+[expr {$padx+12*$fixedWidth}]+$pady]
} -result [list 30x20+[xchar 12]+[yline 1]]

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
    # 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"}
1031
1032
1033
1034
1035
1036
1037
1038
1039


1040
1041
1042
1043
1044
1045
1046
1058
1059
1060
1061
1062
1063
1064


1065
1066
1067
1068
1069
1070
1071
1072
1073







-
-
+
+







    .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] \
    30x20+[xchar 14]+[yline 2] \
    [list [xchar 14] [yline 2] 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: "
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
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







-
-
+
+


















+










-













-
-
+
+













-
-
+
+













-
-
+
+













-
-
+
+













-
-
+
+













-
-
+
+













-
-
+
+













-
-
+
+
















-
-
+
+
-







    .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]]
    40x10+[expr {[xchar [expr {37-25}]]+30}]+[expr {[yline 2]+(20-10)/2}] \
    [list [expr {[xchar [expr {37-25}]]+30}] [expr {[yline 2]+(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
    update
    .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]]
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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]]
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1+(($fixedHeight-7)/2)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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]]
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1+($fixedAscent-6)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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]]
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+1+($fixedHeight-7)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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}]]]
    5x[expr {$fixedHeight-2}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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}]]]
    5x[expr {$fixedHeight-2}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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}]]]
    5x[expr {$fixedAscent-1}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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}]]]
    5x[expr {$fixedHeight-2}]+[expr {[xchar 2]+2}]+[expr {[yline 1]+1}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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]]
    5x5+[expr {[xchar 2]+2}]+[expr {[yline 1]+5+(($fixedHeight-5)/2)}] \
    [list [expr {[xchar 2]+2}] [expr {[yline 1]+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
1320
1321
1322
1323
1324
1325
1326
1327
1328

1329
1330
1331
1332
1333
1334
1335
1346
1347
1348
1349
1350
1351
1352


1353
1354
1355
1356
1357
1358
1359
1360







-
-
+







    .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]]

    [list [expr {[xchar 6]+30}] [expr {[yline 1]+(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"
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368




1369
1370
1371
1372
1373
1374
1375
1383
1384
1385
1386
1387
1388
1389




1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400







-
-
-
-
+
+
+
+







    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]]
    30x20+[expr {[xchar 6]}]+[yline 1] \
    [list [expr {[xchar 6]}] [yline 1] 30 20] \
    30x20+[expr {[xchar 6]}]+[expr {[yline 1]+30}] \
    [list [expr {[xchar 6]}] [yline 1] 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
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
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







-
+
-










-
+













-
+














-
+















-
+

















-
+














-
+















-
+














-
+















-
+









+





+

+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+
+
+
+
+
+
+
+


-
+













+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






    .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]]
} -result [list 1 [list [expr {[xchar 6]}] [yline 1] 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
    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
    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
    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
    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
    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
    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
    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
    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
    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 {
    set res {}
    pack [text .t]
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    toplevel .tt
    pack [.t peer create .tt.t]
    update
    .t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
    update
    # There is a blue window in the main widget .t but not in the peer .tt.t
    lappend res [.t window cget 1.2 -window]
    lappend res [.tt.t window cget 1.2 -window]
    # Insert a green window in the peer. Warning: the blue window previously
    # inserted in .t at index 1.2 will now be found in .t at index 1.3
    # The underlying linked segments are common in a text widget and its peers.
    .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]]
    .tt.t window create 1.2 -window [frame .tt.t.f -width 25 -height 20 -bg green]
    update
    lappend res [.t window cget 1.2 -window]
    lappend res [.t window cget 1.3 -window]
    # In the peer, the green window still is at 1.2, and there is no window at 1.3
    lappend res [.tt.t window cget 1.2 -window]
    lappend res [.tt.t window cget 1.3 -window]
    # Insert a red window in .t at index 1.2. This replaces the blue window originally at 1.2
    # in .t, because the green window inserted in the peer is not visible from .t, therefore
    # the embedded window found at index 1.2 in .t is the one originally at 1.2 in .t, i.e.
    # the blue one
    .t window configure 1.2 -create {destroy %W.f ; update ; frame %W.f -width 50 -height 7 -bg red}
    update
    # The main widget .t still has a window named .t.f at 1.2. This is NOT the blue
    # frame but the red frame from the -create script, which bears the same name.
    lappend res [.t window cget 1.2 -window]
    # The peer still has its green .tt.t.f at 1.2
    lappend res [.tt.t window cget 1.2 -window]
    # When removing the -window option the create script plays, therefore .t still has
    # the red frame .t.f at 1.2
    .t window configure 1.2 -window {}
    update
    lappend res [.t window configure 1.2 -window] \
        [.tt.t window configure 1.2 -window]
    lappend res [.t window cget 1.2 -window]
    # The -create script associated to index 1.2 applies to all peers (that's the reason
    # why the manual states that "If multiple peer widgets are in use, it is usually simpler
    # to use the -create option if embedded windows are desired in each peer."). Therefore
    # when removing the -window option in the peer, the -create script is run, which replaces
    # the green frame by the red one named as per the -create script, i.e. .tt.t.f
    .tt.t window configure 1.2 -window {}
    update
    lappend res [.tt.t window cget 1.2 -window]
} -cleanup {
    destroy .tt .t
}  -result {{-window {} {} {} {}} {-window {} {} {} {}} {-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}
}  -result {.t.f {} {} .t.f .tt.t.f {} .t.f .tt.t.f .t.f .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
    after 200
    update
} -cleanup {
    destroy .t .f .f2
} -result {}

test textWind-18.2 {text widget deletion triggered by a script bound to embedded window mapping} -setup {
    catch {destroy .t .f}
} -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]
    bind .f <Map> {destroy .t}
    update
    # this shall not crash (bug 1501749)
    after 100 {.t yview end}
    tkwait window .t
} -cleanup {
    destroy .t .f
} -result {}

test textWind-18.3 {embedded window destruction in cascade} -setup {
    catch {destroy .t .f}
    set x 0
} -body {
    pack [text .t]
    button .t.b1
    .t window create 1.0 -window .t.b1
    bind .t.b1 <Destroy> {destroy .t.b2 ; set x 1}
    button .t.b2
    .t window create 2.0 -window .t.b2
    update
    # this shall not crash (bug 54fe7a5e71)
    after 100 {.t delete 1.0 end}
    tkwait variable x
} -cleanup {
    destroy .t .f
} -result {}

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
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 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 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}

155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179




180
181
182
183
184







-
+



















-
-
-
-





    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 )}
    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 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
Changes to tests/ttk/checkbutton.test.
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67







-
+







    }
    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 <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
Changes to tests/ttk/combobox.test.
51
52
53
54
55
56
57










58
59
60
61
62

63





64
65
66
67
68
69
70


71
72

73
74
75

76
77
78
79
80
81
82
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92

93
94
95
96
97
98
99
100







+
+
+
+
+
+
+
+
+
+





+

+
+
+
+
+






-
+
+


+


-
+







} -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.7 {current -- set to 0 index when empty [bug 924835c36d]} -body {
    .cb configure -values {}
    .cb current 0
} -returnCodes error -result {Index 0 out of range}

test combobox-2.8 "current -- set to end index in an empty combobox" -body {
    .cb configure -values {}
    .cb current end
} -returnCodes error -result {index "end" out of range}

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
    update idletasks
    ttk::style configure DerivedStyle.TCombobox -postoffset [list 25 0 0 0]
    if {[tk windowingsystem] == "aqua"} {
	after 500 {
	    pressbutton [expr {[winfo rootx .cb] + 25}] [expr {[winfo rooty .cb] + 25}]
	}
    }
    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 {
test combobox-1890211 "ComboboxSelected event after listbox unposted" \
    -constraints {notAqua} -body {
    # whitebox test...
    pack [ttk::combobox .cb -values [list a b c]]
    update idletasks
    set result [list]
    bind .cb <<ComboboxSelected>> {
    	lappend result Event [winfo ismapped .cb.popdown] [.cb get]
	lappend result Event [winfo ismapped .cb.popdown] [.cb get]
    }
    lappend result Start 0 [.cb get]
    ttk::combobox::Post .cb
    lappend result Post [winfo ismapped .cb.popdown] [.cb get]
    .cb.popdown.f.l selection clear 0 end; .cb.popdown.f.l selection set 1
    ttk::combobox::LBSelected .cb.popdown.f.l
    lappend result Select [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
1
2
3
4
5
6
7
8
9


10
11
12
13
14
15
16









-
-







#
# 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;
70
71
72
73
74
75
76
77

78
79
80

81
82

83
84
85

86
87

88
89

90
91
92
93
94
95
96
68
69
70
71
72
73
74

75
76
77

78
79

80
81
82
83
84
85

86
87

88
89
90
91
92
93
94
95







-
+


-
+

-
+



+

-
+

-
+








# Scrollbar tests.

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
	-expand false -fill x
}  -cleanup {destroy .te .tsb}

test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -constraints failsOnUbuntu -body {
test entry-2.1.1 "Create entry before scrollbar - scrollbar catches up" -body {
    pack [ttk::entry .te -xscrollcommand [list .tsb set]] \
	-expand true -fill both
	    -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"
    focus -force .te ; # needed on some systems such as Ubuntu (see ticket [3c2a3a988f])
    pack [ttk::scrollbar .tsb -orient horizontal -command [list .te xview]] \
    	-expand false -fill x
	    -expand false -fill x
    update ; # no error
    lappend res [expr [lindex [.tsb get] 1] < 1] ; # scrollbar did update
    set 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"}]
104
105
106
107
108
109
110
111
112


113
114
115
116
117
118
119
103
104
105
106
107
108
109


110
111
112
113
114
115
116
117
118







-
-
+
+








# 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 ]
    variable bd 3	;# border + padding + extra space for focus ring
    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
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248







-
+







test entry-6.1 {Update linked variable in write trace} -body {
    proc override args {
	global x
	set x "Overridden!"
    }
    catch {destroy .e}
    set x ""
    trace variable x w override
    trace add variable x write override
    ttk::entry .e -textvariable x
    .e insert 0 "Some text"
    set result [list $x [.e get]]
    set result
} -result {Overridden! Overridden!} -cleanup {
    unset x
    rename override {}
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370



















371
372
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328






























329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360







-
+











-
+

















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



test entry-8.2 "Unset linked variable by deleting namespace" -body {
    namespace eval ::test  { variable foo "bar" }
    pack [ttk::entry .e -textvariable ::test::foo]
    namespace delete ::test
    .e insert end "baz"		;# <== error here
    list [.e cget -textvariable] [.e get] [set foo]
} -returnCodes error -result "*parent namespace doesn't exist*" -match glob
} -returnCodes error -result {can*t set "::test::foo": parent namespace does*t exist} -match glob
# '-result [list ::test::foo "baz" "baz"]' would also be sensible,
# but Tcl namespaces don't work that way.

test entry-8.2a "Followup to test 8.2" -body {
    .e cget -textvariable
} -result ::test::foo -cleanup { destroy .e }
# For 8.2a, -result {} would also be sensible.

test entry-9.1 "Index range invariants" -setup {
    # See bug#1721532 for discussion
    proc entry-9.1-trace {n1 n2 op} {
    	set ::V NO!
	set ::V NO!
    }
    variable V
    trace add variable V write entry-9.1-trace
    ttk::entry .e -textvariable V
} -body {
    set result [list]
    .e insert insert a ; lappend result [.e index insert] [.e index end]
    .e insert insert b ; lappend result [.e index insert] [.e index end]
    .e insert insert c ; lappend result [.e index insert] [.e index end]
    .e insert insert d ; lappend result [.e index insert] [.e index end]
    .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
}
test entry-11.2 {Bug [2a32225cd1] - Navigation in a password made of several words} -setup {
    destroy .e
    pack [ttk::entry .e -show *]
    update
    set res {}
} -body {
    .e insert end "A sample password made of several words"
    .e icursor end
    event generate .e <<PrevWord>>  ; # shall move insert to index 0
    .e delete insert end
    lappend res [.e get]
    .e insert end "A sample password made of several words"
    .e icursor 2
    event generate .e <<NextWord>>  ; # shall move insert to index end
    .e delete 0 insert
    lappend res [.e get]
} -cleanup {
    destroy .e
} -result {{} {}}

tcltest::cleanupTests
Changes to tests/ttk/labelframe.test.
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106

107
108
109
110
111
112
113
92
93
94
95
96
97
98

99
100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
+






-
+







    .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] \
	[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] \
	[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 {}
Changes to tests/ttk/notebook.test.
63
64
65
66
67
68
69

70
71
72
73

74
75
76
77
78
79
80
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81







+



-
+








test notebook-2.4 "tab - set value" -body {
    .nb tab .nb.foo -text "Changed Foo"
    .nb tab .nb.foo -text
} -result "Changed Foo"

test notebook-2.5 "tab - get all options" -body {
    .nb tab .nb.foo -underline 0
    .nb tab .nb.foo
} -result [list \
    -padding 0 -sticky nsew \
    -state normal -text "Changed Foo" -image "" -compound {} -underline -1]
    -state normal -text "Changed Foo" -image "" -compound {} -underline 0]

test notebook-4.1 "Test .nb index end" -body {
    .nb index end
} -result 2

test notebook-4.2 "'end' is not a selectable index" -body {
    .nb select end
92
93
94
95
96
97
98
99

100
101
102
103


104
105
106
107
108
109
110
93
94
95
96
97
98
99

100
101
102


103
104
105
106
107
108
109
110
111







-
+


-
-
+
+








test notebook-5.1 "Virtual events" -body {
    toplevel .t
    set ::events [list]
    bind .t <<NotebookTabChanged>> { lappend events changed %W }

    pack [set nb [ttk::notebook .t.nb]] -expand true -fill both; update
    $nb add [frame $nb.f1]
    $nb add [frame $nb.f1] ;  # triggers <<NotebookTabChanged>> (first tab gets autoselected)
    $nb add [frame $nb.f2]
    $nb add [frame $nb.f3]

    $nb select $nb.f1
    update
    $nb select $nb.f1 ; # does not trigger <<NotebookTabChanged>> (tab to select is already selected)
    update; set events
} -result [list changed .t.nb]

test notebook-5.2 "Virtual events, continued" -body {
    set events [list]
    $nb select $nb.f3
    update ; set events
152
153
154
155
156
157
158

159
160

161
162
163
164
165
166
167
153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169







+

-
+







    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f2
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    update idletasks; lappend result [winfo ismapped $nb.f3]
    lappend result [winfo ismapped $nb.f3]
} -result [list 1 1 2 0 1]

# See 1370833
test notebook-6.2 "Forget selected tab" -setup {
    ttk::notebook .n
    pack .n
    label .n.l -text abc
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

325
326

327
328
329
330
331
332
333
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346







+















+















+















+















+















+















+















+















+















+


+







    $nb select $nb.f1
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f1]
    $nb hide $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f1]
} -result [list 0 1 1 0]

test notebook-6.4 "Forget first tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f1
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f1]
    $nb forget $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f1]
} -result [list 0 1 0 0]

test notebook-6.5 "Hide last tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f3
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f3]
    $nb hide $nb.f3
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f3]
} -result [list 2 1 1 0]

test notebook-6.6 "Forget a middle tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f2
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 0]

test notebook-6.7 "Hide a middle tab when it's the current" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f2
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 2 0]

test notebook-6.8 "Forget a non-current tab < current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 0 1]

test notebook-6.9 "Hide a non-current tab < current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f1
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.10 "Forget a non-current tab > current" -setup {
    pack [set nb [ttk::notebook .nb]] ; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb forget $nb.f3
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.11 "Hide a non-current tab > current" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [winfo ismapped $nb.f2]
    $nb hide $nb.f3
    update idletasks
    lappend result [$nb index current] [winfo ismapped $nb.f2]
} -result [list 1 1 1 1]

test notebook-6.12 "Hide and re-add a tab" -setup {
    pack [set nb [ttk::notebook .nb]]; update
    $nb add [ttk::frame $nb.f1]
    $nb add [ttk::frame $nb.f2]
    $nb add [ttk::frame $nb.f3]
    $nb select $nb.f2
} -cleanup  {
    destroy $nb
} -body {
    set result [list]
    lappend result [$nb index current] [$nb tab $nb.f2 -state]
    $nb hide $nb.f2
    update idletasks
    lappend result [$nb index current] [$nb tab $nb.f2 -state]
    $nb add $nb.f2
    update idletasks
    lappend result [$nb index current] [$nb tab $nb.f2 -state]
} -result [list 1 normal 2 hidden 2 normal]

#
# Insert:
#
unset nb
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420







-
+







    .nb insert 1 3
    .nb index current
} -result 4

test notebook-7.8a "move tabs - current tab undisturbed - exhaustive" -body {
    .nb select .nb.f0
    foreach i {0 1 2 3 4} {
    	.nb insert $i .nb.f$i
	.nb insert $i .nb.f$i
    }

    foreach i {0 1 2 3 4} {
	.nb select .nb.f$i
	foreach j {0 1 2 3 4} {
	    foreach k {0 1 2 3 4} {
		.nb insert $j $k
450
451
452
453
454
455
456
457

458
459
460
461
462
463
464
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477







-
+







} -result [list "" .nb.l1] -cleanup { destroy .nb }

test notebook-1817596-2 "error in insert should have no effect" -body {
    pack [ttk::notebook .nb]
    .nb insert end [ttk::label .nb.l1]
    .nb insert end [ttk::label .nb.l2]
    list \
    	[catch { .nb insert .l2 0 -badoption badvalue } err] \
	[catch { .nb insert .l2 0 -badoption badvalue } err] \
	[.nb tabs] \
} -result [list 1 [list .nb.l1 .nb.l2]] -cleanup { destroy .nb }

test notebook-1817596-3 "insert/configure" -body {
    pack [ttk::notebook .nb]
    .nb insert end [ttk::label .nb.l0] -text "L0"
    .nb insert end [ttk::label .nb.l1] -text "L1"
507
508
509
510
511
512
513
514





































515
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








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


test notebook-1343984-2 "don't autoselect on destroy" -body {
    set ::history [list]
    destroy .nb
    update
    set ::history
} -result [list DESTROY .nb.frame1 DESTROY .nb.frame2 DESTROY .nb.frame3]

test notebook-198376af5a {moving tab position to a different edge} -body {
    destroy .nb
    ttk::notebook .nb -width 200 -height 100 -padding 0
    ttk::frame .nb.f1
    ttk::frame .nb.f2
    .nb add .nb.f1 -text "One"
    .nb add .nb.f2 -text "Two"
    pack .nb
    update
    ttk::style configure TNotebook -tabposition s
    update
    expr {[winfo y .nb.f1] < 10}
} -result 1

test notebook-9.1 "move last tab by numerical index" -body {
    ::ttk::notebook .n
    foreach tabs {TabA TabB TabC} {
	::ttk::entry .n.[string tolower $tabs]
	.n add .n.[string tolower $tabs] -text $tabs
    }
   .n insert 0 2  ; # allowed: TabC moves to first tab position
   .n insert 0 3  ; # not allowed: position 3 is after last tab
} -cleanup {
    destroy .n
} -result {Slave index 3 out of bounds} -returnCodes error
test notebook-9.2 "move first tab to last position by numerical index" -body {
    ::ttk::notebook .n
    foreach tabs {TabA TabB TabC} {
	::ttk::entry .n.[string tolower $tabs]
	.n add .n.[string tolower $tabs] -text $tabs
    }
   .n insert 2 0  ; # allowed: TabA moves to last tab position
   .n insert 3 0  ; # not allowed: position 3 is after last tab
} -cleanup {
    destroy .n
} -result {Slave index 3 out of bounds} -returnCodes error

tcltest::cleanupTests
Changes to tests/ttk/panedwindow.test.
1
2
3
4
5
6
7
8
9
10
11
12
















13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35












+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







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 {
    ttk::panedwindow .pw
} -result .pw

test panedwindow-1.0.1 "Make sure pane 0 command doesn't crash on empty pane - bug e6140f3404" -body {
    .pw pane 0
} -result {Slave index 0 out of bounds} -returnCodes error

test panedwindow-1.0.2 "Make sure pane -1 command doesn't crash on empty pane - bug e6140f3404" -body {
    .pw pane -1
} -result {Slave index -1 out of bounds} -returnCodes error

test panedwindow-1.0.3 "Make sure forget 0 command doesn't crash on empty pane - bug e6140f3404" -body {
    .pw forget 0
} -result {Slave index 0 out of bounds} -returnCodes error

test panedwindow-1.0.4 "Make sure forget -1 command doesn't crash on empty pane - bug e6140f3404" -body {
    .pw forget -1
} -result {Slave index -1 out of bounds} -returnCodes error

test panedwindow-1.1 "Make sure empty panedwindow doesn't crash" -body {
    pack .pw -expand true -fill both
    update
}

test panedwindow-1.2 "Add a pane" -body {
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182







-
+







# checkorder $winlist --
#	Ensure that Y coordinates windows in $winlist are strictly increasing.
#
proc checkorder {winlist} {
    set pos -1
    set positions [list]
    foreach win $winlist {
    	lappend positions [set nextpos [winfo y $win]]
	lappend positions [set nextpos [winfo y $win]]
	if {$nextpos <= $pos} {
	    error "window $win out of order ($positions)"
	}
	set pos $nextpos
    }
}

199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229







-
+








### sashpos tests.
#
proc sashpositions {pw} {
    set positions [list]
    set npanes [llength [winfo children $pw]]
    for {set i 0} {$i < $npanes - 1} {incr i} {
    	lappend positions [$pw sashpos $i]
	lappend positions [$pw sashpos $i]
    }
    return $positions
}

test paned-sashpos-setup "Setup for sash position test" -body {
    ttk::style theme use default
    ttk::style configure -sashthickness 5
Changes to tests/ttk/progressbar.test.
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85







































86







-
+








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

    .pb configure -variable PB		;# @@@
    set PB 5
    .pb step
    set PB
} -result 6.0

test progressbar-2.5 "error in write trace" -body {
    trace variable PB w { error "YIPES!" ;# }
    trace add variable PB write { error "YIPES!" ;# }
    .pb step
    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
Changes to tests/ttk/radiobutton.test.
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19











-
+







#
# 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 .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] \
	;
}
test radiobutton-1.2 "Radiobutton invoke" -body {
    .rb1 invoke
    set ::choice
Changes to tests/ttk/scrollbar.test.
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38







-
+







}

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::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 {
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
67
68
69
70
71
72
73















74






























75
76
77
78

79
80
81
82
83
84
85
86







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-
+







    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 ;# }
    trace add variable v write { 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
Changes to tests/ttk/spinbox.test.
134
135
136
137
138
139
140
141
142

143
144

145

146
147


148


149
150
151
152
153
154
155
134
135
136
137
138
139
140

141
142
143

144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159







-

+

-
+

+


+
+
-
+
+







} -body {
    .sb configure -validate bogus
} -cleanup {
    destroy .sb
} -returnCodes error -result {bad validate "bogus": must be all, key, focus, focusin, focusout, or none}

test spinbox-1.8.4 "-validate option: " -setup {
    set ::spinbox_test {}
    ttk::spinbox .sb -from 0 -to 100
    set ::spinbox_test {}
} -body {
    .sb configure -validate all -validatecommand {lappend ::spinbox_test %P}
    .sb configure -validate all -validatecommand {set ::spinbox_test %P}
    pack .sb
    update idletasks
    .sb set 50
    focus -force .sb
    set ::spinbox_wait 0
    set timer [after 100 {set ::spinbox_wait 1}]
    after 500 {set ::spinbox_wait 1} ; vwait ::spinbox_wait
    vwait ::spinbox_wait
    after cancel $timer
    set ::spinbox_test
} -cleanup {
    destroy .sb
} -result 50


test spinbox-2.0 "current command -- unset should be 0" -constraints nyi -setup {
278
279
280
281
282
283
284














285
286
287
288
289
290
291
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309







+
+
+
+
+
+
+
+
+
+
+
+
+
+







        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}

test spinbox-11.2 {Bugs [2a32225cd1] and [9fa3e08243]} -setup {
    destroy .s
    pack [ttk::spinbox .s]
    update
} -body {
    .s insert end "A sample text"
    .s icursor end
    event generate .s <<PrevWord>>  ; # shall move insert to index 9
    .s delete insert end
    .s get
} -cleanup {
    destroy .s
} -result {A sample }


# 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
Changes to tests/ttk/treetags.test.
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-
+








    itemConstraints $tv {}
}
#
###

test treetags-1.0 "Setup" -body {
    set tv [ttk::treeview .tv]
    set tv [ttk::treeview .tv -columns "A B C"]
    .tv insert {} end -id item1 -text "Item 1"
    pack .tv
} -cleanup {
    treeConstraints $tv
}

test treetags-1.1 "Bad tag list" -body {
58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72







-
+







    treeConstraints $tv
} -result [list tag1]

test treetags-1.3 "tag has - test" -body {
    $tv insert {} end -id item2 -text "Item 2" -tags tag2
    set result [list]
    foreach item {item1 item2} {
    	foreach tag {tag1 tag2 tag3} {
	foreach tag {tag1 tag2 tag3} {
	    lappend result $item $tag [$tv tag has $tag $item]
	}
    }
    set result
} -cleanup {
    treeConstraints $tv
} -result [list \
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133


134
135
136
137
138
139

140
141

142
143
144
145
146
147
148

149
150
151

152
153

154
155
156
157
158
159
160
110
111
112
113
114
115
116






117
118
119
120
121
122
123
124
125


126
127
128
129
130
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.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>
    $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 Key
    focus -force $tv ; update	;# needed so [event generate] delivers KeyPress
    $tv focus item1
    event generate $tv <a>
    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 <Key> [list set ::KEY2 %A]
    $tv tag bind tag2 <KeyPress> [list set ::KEY2 %A]

    $tv focus item1
    event generate $tv <b>
    event generate $tv <KeyPress-b>
    $tv focus item2
    event generate $tv <c>
    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 {
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211







-
+







    $tv tag configure tag2 -font {times 20}
}

test treetags-3.4 "stomp tags in tag binding procedure" -body {
    set result [list]
    $tv tag bind rm1 <<Remove>> { lappend ::result rm1 [%W focus] <<Remove>> }
    $tv tag bind rm2 <<Remove>> {
    	lappend ::result rm2 [%W focus] <<Remove>>
	lappend ::result rm2 [%W focus] <<Remove>>
	%W item [%W focus] -tags {tag1}
    }
    $tv tag bind rm3 <<Remove>> { lappend ::result rm3 [%W focus] <<Remove>> }

    $tv item item1 -tags {rm1 rm2 rm3}
    $tv focus item1
    event generate $tv <<Remove>>
Changes to tests/ttk/treeview.test.
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36


37
38






39

















40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61

62
63
64
65
66
67
68
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30

31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85

86
87
88
89
90
91
92
93







-
+











-
+




-
+
+


+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+














-
+



-
+







#	Traverse the tree to make sure the item data structures
#	are properly linked.
#
#	Since [$tv children] follows ->next links and [$tv index]
#	follows ->prev links, this should cover all invariants.
#
proc consistencyCheck {tv {item {}}} {
    set i 0;
    set i 0
    foreach child [$tv children $item] {
	assert {[$tv parent $child] == $item} "parent $child = $item"
	assert {[$tv index $child] == $i} "index $child [$tv index $child]=$i"
	incr i
	consistencyCheck $tv $child
    }
}

proc assert {expr {message ""}} {
    if {![uplevel 1 [list expr $expr]]} {
        set error "PANIC! PANIC! PANIC: $message ($expr failed)"
    	puts stderr $error
	puts stderr $error
	error $error
    }
}

test treeview-0 "treeview test - setup" -body {
proc tvSetup {} {
    destroy .tv
    ttk::treeview .tv -columns {a b c}
    pack .tv -expand true -fill both
    .tv column #0 -width 50
    .tv column a -width 50
    .tv column b -width 50
    .tv column c -width 50
    # Make sure everything is created and updated
    tkwait visibility .tv
    update
    after 10
    update
}
proc tvSetupWithItems {} {
    tvSetup
    .tv insert {} end -id nn -text "nn"
    .tv insert nn end -id nn.n1 -text "nn.1"
    .tv insert nn end -id nn.n2 -text "nn.3"
    .tv insert nn end -id nn.n3 -text "nn.3"
    for {set t 2} {$t < 100} {incr t} {
        .tv insert {} end -id nn$t -text "nn$t"
        if {$t % 3 == 0} {
            .tv insert nn$t end -id nn$t.n1 -text "nn$t.n1"
            .tv insert nn$t end -id nn$t.n2 -text "nn$t.n2"
            .tv insert nn$t end -id nn$t.n3 -text "nn$t.n3"
        }
    }
}

test treeview-1.1 "columns" -body {
    tvSetup
    .tv configure -columns {a b c}
}

test treeview-1.2 "Bad columns" -body {
    #.tv configure -columns {illegal "list"value}
    ttk::treeview .badtv -columns {illegal "list"value}
} -returnCodes error -result "list element in quotes followed by*" -match glob

test treeview-1.3 "bad displaycolumns" -body {
    .tv configure -displaycolumns {a b d}
} -returnCodes error -result "Invalid column index d"

test treeview-1.4 "more bad displaycolumns" -body {
    .tv configure -displaycolumns {1 2 3}
} -returnCodes error -result "Column index 3 out of bounds"
} -returnCodes error -result {Column index 3 out of bounds}

test treeview-1.5 "Don't forget to check negative numbers" -body {
    .tv configure -displaycolumns {1 -2 3}
} -returnCodes error -result "Column index -2 out of bounds"
} -returnCodes error -result {Column index -2 out of bounds}

# Item creation.
#
test treeview-2.1 "insert -- not enough args" -body {
    .tv insert
} -returnCodes error -result "wrong # args: *" -match glob

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
113
114
115
116
117
118
119


120
121
122
123
124
125
126







-
-








test treeview-2.8 "insert -- new node at end" -body {
    .tv insert {} end -id lastnode
    consistencyCheck .tv
    .tv children {}
} -result [list newnode lastnode]

consistencyCheck .tv

test treeview-2.9 "insert -- new node at beginning" -body {
    .tv insert {} 0 -id firstnode
    consistencyCheck .tv
    .tv children {}
} -result [list firstnode newnode lastnode]

test treeview-2.10 "insert -- one more node" -body {
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236







+



-







    .tv detach newnode
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone]

test treeview-3.11 "Can't detach root item" -body {
    .tv detach [list {}]
} -cleanup {
    update
    consistencyCheck .tv
} -returnCodes error -result "Cannot detach root item"
consistencyCheck .tv

test treeview-3.12 "Reattach" -body {
    .tv move newnode {} end
    consistencyCheck .tv
    .tv children {}
} -result [list newfirstone firstnode anotherone onemore lastnode newlastone newnode]

298
299
300
301
302
303
304
305

306
307
308
309
310
311
312
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335







-
+








test treeview-5.6 "set illegal cell" -body {
    .tv set newnode #0 YYY
} -returnCodes error -result "Display column #0 cannot be set"

test treeview-5.7 "set illegal cell" -body {
    .tv set newnode 3 YY	;# 3 == current #columns
} -returnCodes error -result "Column index 3 out of bounds"
} -returnCodes error -result {Column index 3 out of bounds}

test treeview-5.8 "set display columns" -body {
    .tv configure -displaycolumns [list 2 1 0]
    .tv set newnode #1 X
    .tv set newnode #2 Y
    .tv set newnode #3 Z
    .tv item newnode -values
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
369
370
371
372
373
374
375


376
377
378
379
380
381
382







-
-








test treeview-6.1.1 "delete" -body {
    .tv delete b
    consistencyCheck .tv
    list [.tv exists b] [.tv children dtest]
} -result [list 0 [list a c d e]]

consistencyCheck .tv

test treeview-6.2 "delete - duplicate items in list" -body {
    .tv delete [list a e a e]
    consistencyCheck .tv
    .tv children dtest
} -result [list c d]

test treeview-6.3 "delete - descendants removed" -body {
423
424
425
426
427
428
429
430
431
432



433
434
435
436
437
438
439
440
444
445
446
447
448
449
450



451
452
453
454
455
456
457
458
459
460
461







-
-
-
+
+
+








    # Just check to make sure the test suite so far has left
    # us in the state we expect to be in:
    list [.tv parent newnode] [.tv children newnode]
} -result [list {} [list newnode.n1 newnode.n2 newnode.n3]]

test treeview-7.6 "Replace children - illegal move" -body {
    .tv children newnode.n1 [list newnode.n1 newnode.n2 newnode.n3]
} -returnCodes error -result "Cannot insert newnode.n1 as descendant of newnode.n1"

consistencyCheck .tv
} -cleanup {
    consistencyCheck .tv
} -returnCodes error -result "Cannot insert newnode.n1 as descendant of newnode.n1"

test treeview-8.0 "Selection set" -body {
    .tv selection set [list newnode.n1 newnode.n3 newnode.n2]
    .tv selection
} -result [list newnode.n1 newnode.n2 newnode.n3]

test treeview-8.1 "Selection add" -body {
    .tv selection add [list newnode]
456
457
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
477
478
479
480
481
482
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







-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+

+
+
-
+

-
-
-
-
-
+
+
+
+
+

-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
-
-
+
+
+

+
+
+
+
+
+
+
+
+

+
+
-
+







+













+
+
+
-
+







    .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
test treeview-8.7 "<<TreeviewSelect>> when deleting items" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    .tv selection add myItem1
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv delete myItem2  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv delete myItem1  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {2}

test treeview-8.8 "<<TreeviewSelect>> when setting the selection" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv selection set ""       ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv selection set myItem1  ; # <<TreeviewSelect>> triggers
    update
    # Current implementation generates an event for this case
    set val 3
    .tv selection set myItem1  ; # (already selected)
    update
    set val 4
    .tv selection set {myItem1 myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set val 5
    .tv selection set {myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {2 3 4 5}

test treeview-8.9 "<<TreeviewSelect>> when removing items from the selection" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv selection set myItem1
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv selection remove ""       ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv selection remove myItem1  ; # <<TreeviewSelect>> triggers
    update
    set val 3
    .tv selection remove myItem1  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result 1
} -result {2}

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
test treeview-8.10 "<<TreeviewSelect>> when adding items in the selection" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    .tv insert "" end -id myItem3 -text ThirdItem
    update
    bind .tv <<TreeviewSelect>> {lappend res 1}
    set res 0
    .tv delete doomed
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res {}
    set val 1
    .tv selection add myItem2  ; # <<TreeviewSelect>> triggers
    update
    set val 2
    .tv selection add myItem2  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 3
    .tv selection add myItem3  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {1 3}

test treeview-8.11 "<<TreeviewSelect>> when toggling" -body {
    .tv delete [.tv children {}]
    .tv insert "" end -id myItem1 -text FirstItem
    .tv insert "" end -id myItem2 -text SecondItem
    .tv insert "" end -id myItem3 -text ThirdItem
    update
    bind .tv <<TreeviewSelect>> {lappend res $val}
    set res [expr {$res == 0}]
    .tv delete selectedDoomed
    set res {}
    set val 1
    .tv selection toggle ""  ; # no <<TreeviewSelect>> (selection unchanged)
    update
    set val 2
    .tv selection toggle {myItem1 myItem3}  ; # <<TreeviewSelect>> triggers
    update
    set val 3
    .tv selection toggle {myItem3 myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set val 4
    .tv selection toggle {myItem3 myItem2}  ; # <<TreeviewSelect>> triggers
    update
    set res
} -cleanup {
    bind .tv <<TreeviewSelect>> {}
} -result {1 1}
} -result {2 3 4}

### NEED: more tests for see/yview/scrolling

proc scrollcallback {args} {
    set ::scrolldata $args
}
test treeview-9.0 "scroll callback - empty tree" -body {
    tvSetup
    .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
    # This is sensitive to the exact layout of a tree.
    # It assumes that (8,8) should be far enough in to be in the tree,
    # while still being in the first item.
    .tree identify item 2 2
    .tree identify item 8 8
} -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} \
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
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







+
+






-
-
-
-
+
+
+
+



+
+
+
+
+




-
+





-
+





-
+





-
+


-
+



-
-
+
+




-
-
+
+




-
-
+
+

-







+
-
-
+
+


+
+







+







    }
    return $result
}

test treeview-identify-setup "identify series - setup" -body {
    destroy .tv
    ttk::setTheme default
    ttk::style configure Treeview -rowheight 10m
    ttk::style configure Treeview.Heading -font {Arial 10}
    ttk::treeview .tv -columns [list A B C]
    .tv insert {} end -id branch -text branch -open true
    .tv insert branch end -id item1 -text item1
    .tv insert branch end -id item2 -text item2
    .tv insert branch end -id item3 -text item3

    .tv column #0 -width 50	;# 0-50
    .tv column A -width 50	;# 50-100
    .tv column B -width 50	;# 100-150
    .tv column C -width 50	;# 150-200 (plus slop for margins)
    .tv column #0 -width 200	;# 0-200
    .tv column A -width 200	;# 200-400
    .tv column B -width 200	;# 400-600
    .tv column C -width 200	;# 600-800 (plus slop for margins)

    wm geometry . {} ; pack .tv ; update
}
# treeview-identify-setup sets heading row font to Arial with size 10 points,
# so the heading line center y-coordinate is (in pixels):
set yHLC [expr {([font metrics {Arial 10} -linespace] + 2) / 2.0}]
# which makes the following in millimeters:
set yHLC [expr {$yHLC / [winfo screenwidth .] * [winfo screenmmwidth .]}]

test treeview-identify-1 "identify heading" -body {
    .tv configure -show {headings tree}
    update idletasks
    identify* .tv {region column} 10 10
    identify* .tv {region column} 10 ${yHLC}m
} -result [list heading #0]

test treeview-identify-2 "identify columns" -body {
    .tv configure -displaycolumns #all
    update idletasks
    columnids .tv [identify* .tv column 25 10  75 10  125 10  175 10]
    columnids .tv [identify* .tv column 100 ${yHLC}m  300 ${yHLC}m  500 ${yHLC}m  700 ${yHLC}m]
} -result [list {} A B C]

test treeview-identify-3 "reordered columns" -body {
    .tv configure -displaycolumns {B A C}
    update idletasks
    columnids .tv [identify* .tv column 25 10  75 10  125 10  175 10]
    columnids .tv [identify* .tv column 100 ${yHLC}m  300 ${yHLC}m  500 ${yHLC}m  700 ${yHLC}m]
} -result [list {} B A C]

test treeview-identify-4 "no tree column" -body {
    .tv configure -displaycolumns #all -show {headings}
    update idletasks
    identify* .tv {region column} 25 10  75 10  125 10  175 10
    identify* .tv {region column} 100 ${yHLC}m  300 ${yHLC}m  500 ${yHLC}m  700 ${yHLC}m
} -result [list heading #1 heading #2 heading #3 nothing {}]

# Item height in default theme is 20px
# Item height (-rowheight) is 10 millimeters (set in treeview-identify-setup)
test treeview-identify-5 "vertical scan - no headings" -body {
    .tv configure -displaycolumns #all -show {tree}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 50  25 70  25 90
} -result [list tree branch tree item1 tree item2 tree item3 nothing {}]
    identify* .tv {region item} 100 5m  100 15m  100 35m  100 45m  100 55m  100 65m
} -result [list tree branch tree item1 tree item3 nothing {} nothing {} nothing {}]

test treeview-identify-6 "vertical scan - with headings" -body {
    .tv configure -displaycolumns #all -show {tree headings}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 50  25 70  25 90
} -result [list heading {} tree branch tree item1 tree item2 tree item3]
    identify* .tv {region item} 100 ${yHLC}m  100 [expr {$yHLC+5}]m  100 [expr {$yHLC+15}]m  100 [expr {$yHLC+35}]m  100 [expr {$yHLC+45}]m
} -result [list heading {} tree branch tree item1 tree item3 nothing {}]

test treeview-identify-7 "vertical scan - headings, no tree" -body {
    .tv configure -displaycolumns #all -show {headings}
    update idletasks
    identify* .tv {region item} 25 10  25 30  25 50  25 70  25 90
} -result [list heading {} cell branch cell item1 cell item2 cell item3]
    identify* .tv {region item} 100 ${yHLC}m  100 [expr {$yHLC+5}]m  100 [expr {$yHLC+15}]m  300 [expr {$yHLC+35}]m  100 [expr {$yHLC+45}]m
} -result [list heading {} cell branch cell item1 cell item3 nothing {}]

# In default theme, -indent and -itemheight both 20px
# Disclosure element name is "Treeitem.indicator"
set disclosure "*.indicator"
test treeview-identify-8 "identify element" -body {
    .tv configure -show {tree}
    .tv insert branch  0 -id branch2 -open true
    .tv insert branch2 0 -id branch3 -open true
    .tv insert branch3 0 -id leaf3
    ttk::style configure Treeview -indent 8m
    update idletasks;
    identify* .tv {item element} 10 10  30 30  50 50
    update idletasks
    identify* .tv {item element} 4m 5m  12m 15m  20m 25m
} -match glob -result [list \
	branch $disclosure branch2 $disclosure branch3 $disclosure]

ttk::style configure Treeview -rowheight 20

# See #2381555
test treeview-identify-9 "identify works when horizontally scrolled" -setup {
    .tv configure -show {tree headings}
    foreach column {#0 A B C} {
	.tv column $column -stretch 0 -width 50
    }
    # Scrollable area is 200, visible is 100
    place .tv -x 0 -y 0 -width 100
} -body {
    set result [list]
    foreach xoffs {0 50 100} {
	.tv xview $xoffs ; update
	lappend result [identify* .tv {region column} 10 10 60 10]
    }
685
686
687
688
689
690
691
692

693
694
695
696
697
698
699
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824







-
+







}

### NEED: tests for focus item, selection

### Misc. tests:

destroy .tv
test treeview-10.1 "Root node properly initialized (#1541739)" -setup {
test treeview-1541739 "Root node properly initialized (#1541739)" -setup {
    ttk::treeview .tv
    .tv insert {} end -id a
    .tv see a
} -cleanup {
    destroy .tv
}

830
831
832
833
834
835
836
837






























838
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








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

    .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}

test treeview-bc602049ab "treeview with custom background does not change size when switching themes" -setup {
    image create photo tvbg -data {
	iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAnXAAAJ1wG
	xbhe3AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAACJJREFUOI
	1jPLF9+38GKgImaho2auCogaMGjho4auBQMhAAyR0DXUEyypsAAAAASUVORK5CYII=
    }
    ttk::style theme create foo-bc602049ab -parent clam -settings {
      ttk::style element create Treeview.field image tvbg -width 0 -height 0
    }
    ttk::style theme use foo-bc602049ab
    pack [ttk::treeview .tv]
    update idletasks
} -body {
    set g1 [winfo geometry .tv]
    ttk::style theme use foo-bc602049ab
    update idletasks
    set g2 [winfo geometry .tv]
    expr {$g1 eq $g2 ? 1 : "$g1 --> $g2"}
} -cleanup {
    destroy .tv
    image delete tvbg
} -result {1}

test treeview-6ee162c3d9 "style configure Treeview -rowheight 0" -setup {
    tvSetupWithItems
} -body {
    ttk::style configure Treeview -rowheight 0  ; # shall not crash
    update
} -result {}

tcltest::cleanupTests
Changes to tests/ttk/ttk.test.
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+











-
+







# Do these early, so any memory corruption has a longer time to cause a crash.
#
proc selfdestruct {w args} {
    destroy $w
}
test ttk-6.1 "Self-destructing checkbutton" -body {
    pack [ttk::checkbutton .sd -text "Self-destruction" -variable ::sd]
    trace variable sd w [list selfdestruct .sd]
    trace add variable sd write [list selfdestruct .sd]
    update
    .sd invoke
} -returnCodes error
test ttk-6.2 "Checkbutton self-destructed" -body {
    winfo exists .sd
} -result 0

# test ttk-6.3 not applicable [see #2175411]

test ttk-6.4 "Destroy widget in configure" -setup {
    set OUCH ouch
    trace variable OUCH r { kill.b }
    trace add variable OUCH read { kill.b }
    proc kill.b {args} { destroy .b }
} -cleanup {
    unset OUCH
} -body {
    pack [ttk::checkbutton .b]
    set rc [catch { .b configure -variable OUCH } msg]
    list $rc $msg [winfo exists .b] [info commands .b]
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97







-
+







    .b invoke
    destroy .b
    set ::A
} -result {it worked}

test ttk-6.9 "Bad font spec in styles" -setup {
    ttk::style theme create badfont -settings {
    	ttk::style configure . -font {Helvetica 12 Bogus}
	ttk::style configure . -font {Helvetica 12 Bogus}
    }
    ttk::style theme use badfont
} -cleanup {
    ttk::style theme use default
} -body {
    pack [ttk::label .l -text Hi! -font {}]
    event generate .l <Expose>
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139


140
141
142
143
144
145
146
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121

122
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 {
    catch {ttk::label .l} errmsg
    list $errmsg [info commands .l] [winfo exists .l]
} -result [list {bad cursor spec "badCursor"} {} 0]

test ttk-construction-failure-2 "Destroy widget in constructor" -setup {
    set OUCH ouch
    trace variable OUCH r { kill.b }
    trace add variable OUCH read { kill.b }
    proc kill.b {args} { destroy .b }
} -cleanup {
    unset OUCH
} -body {
    list \
	[catch { ttk::checkbutton .b -variable OUCH } msg] \
	$msg \
    	[winfo exists .b] \
	[winfo exists .b] \
	[info commands .b] \
	;
} -result [list 1 "widget has been destroyed" 0 {}]

test ttk-selfdestruct-ok-1 "Intentional self-destruction" -body {
    # see #2298720
    toplevel .t
    ttk::button .t.b -command [list destroy .t]
    .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
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 {}

154
155
156
157
158
159
160
161

162
163
164

165
166
167
168
169
170
171
154
155
156
157
158
159
160

161
162
163

164
165
166
167
168
169
170
171







-
+


-
+








proc checkstate {w} {
    foreach statespec {
	{!active !disabled}
	{!active disabled}
	{active !disabled}
	{active disabled}
    	active
	active
	disabled
    } {
    	lappend result [$w instate $statespec]
	lappend result [$w instate $statespec]
    }
    set result
}

# NB: this will fail if the top-level window pops up underneath the cursor
test ttk-2.0 "Check state" -body {
    checkstate .t
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221







-
+







    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>}
    after 50 {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
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258







-
+







test ttk-3.2 "Propagate errors from variable traces" -body {
    set A 0
    trace add variable A write {error "failure" ;# }
    ttk::checkbutton .cb -variable A
    .cb invoke
} -cleanup {
    unset ::A ; destroy .cb
} -returnCodes error -result {can't set "A": failure}
} -returnCodes error -match glob -result {can*t set "A": failure}

test ttk-3.3 "Constructor failure with cursor" -body {
    ttk::button .b -cursor bottom_right_corner -style BadStyle
} -returnCodes error -result "Layout BadStyle not found"

test ttk-3.4 "SF#2009213" -body {
    ttk::style configure TScale -sliderrelief {}
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307







-
+







	# @@@ but that's not really feasible in the current framework.
    }
    pack [ttk::button .tb1 -text "Ouch"]
    ttk::style theme use alt
    update;
    # As long as we haven't crashed, everything's OK
    ttk::style theme settings alt {
    	ttk::style configure TButton -font TkDefaultFont
	ttk::style configure TButton -font TkDefaultFont
    }
    ttk::style theme use default
    destroy .tb1
}

#
# -compound tests:
384
385
386
387
388
389
390
391

392
393
394
395
396

397
398
399
400
401
402
403
384
385
386
387
388
389
390

391
392
393
394
395

396
397
398
399
400
401
402
403







-
+




-
+







    icon blank
} -cleanup { destroy .b }

#------------------------------------------------------------------------

test ttk-9.1 "Traces on nonexistant namespaces" -body {
    ttk::checkbutton .tcb -variable foo::bar
} -returnCodes error -result "*parent namespace doesn't exist*" -match glob
} -returnCodes error -result "*parent namespace does*t exist" -match glob

test ttk-9.2 "Traces on nonexistant namespaces II" -body {
    ttk::checkbutton .tcb -variable X
    .tcb configure -variable foo::bar
} -returnCodes error -result "*parent namespace doesn't exist*" -match glob
} -returnCodes error -result "*parent namespace does*t exist" -match glob

test ttk-9.3 "Restore saved options on configure error" -body {
    .tcb cget -variable
} -result X

test ttk-9.4 "Textvariable tests" -body {
    set tcbLabel "Testing..."
435
436
437
438
439
440
441









442
443
444
445
446
447
448
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457







+
+
+
+
+
+
+
+
+








test ttk-9.8 "-textvariable overrides -text" -body {
    ttk::label .tl -textvariable TV
    set TV Foo
    .tl configure -text Bar
    .tl cget -text
} -cleanup { destroy .tl } -result "Foo"

test ttk-9.9 "default for -justify" -body {
    ttk::label .tl
    .tl cget -justify
} -cleanup { destroy .tl } -result "left"
test ttk-9.10 "default for -anchor" -body {
    ttk::label .tl
    .tl cget -anchor
} -cleanup { destroy .tl } -result "w"

#
# Frame widget tests:
#

test ttk-10.1 "ttk::frame -class resource" -body {
    ttk::frame .f -class Foo
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
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







-
+













-
+




-
+




-
+







-
+







    .tb1 configure -style badstyle
} -cleanup {
    destroy .tb1
} -returnCodes error -result "*badstyle not found*" -match glob

test ttk-13.5 "Custom layouts -- missing element definition" -body {
    ttk::style layout badstyle {
    	NoSuchElement
	NoSuchElement
    }
    ttk::button .tb1 -style badstyle
} -cleanup {
    destroy .tb1
} -result .tb1
# @@@ Should: signal an error, possibly a background error.

#
# See #793909
#

test ttk-14.1 "-variable in nonexistant namespace" -body {
    ttk::checkbutton .tw -variable ::nsn::foo
} -returnCodes error -result {can't trace *: parent namespace doesn't exist} \
} -returnCodes error -result {can*t trace "::nsn::foo": parent namespace does*t exist} \
  -match glob -cleanup { destroy .tw }

test ttk-14.2 "-textvariable in nonexistant namespace" -body {
    ttk::label .tw -textvariable ::nsn::foo
} -returnCodes error -result {can't trace *: parent namespace doesn't exist} \
} -returnCodes error -result {can*t trace "::nsn::foo": parent namespace does*t exist} \
  -match glob -cleanup { destroy .tw }

test ttk-14.3 "-textvariable in nonexistant namespace" -body {
    ttk::entry .tw -textvariable ::nsn::foo
} -returnCodes error -result {can't trace *: parent namespace doesn't exist} \
} -returnCodes error -result {can*t trace "::nsn::foo": parent namespace does*t exist} \
  -match glob -cleanup { destroy .tw }

test ttk-15.1 {Bug 3062331} -setup {
    destroy .b
} -body {
    set Y {}
    ttk::button .b -textvariable Y
    trace variable Y u "destroy .b; #"
    trace add variable Y unset "destroy .b; #"
    unset Y
} -cleanup {
    destroy .b
} -result {}

test ttk-15.2 {Bug 3341056} -setup {
    proc foo {} {
651
652
653
654
655
656
657
658

659
660
661
662
660
661
662
663
664
665
666

667
668
669
670
671







-
+




     ttk::style element create plain.background from
} -returnCodes error -result [wrong#args theme ?element?]

test ttk-ensemble-5 "style element create: valid" -body {
     ttk::style element create plain.background from default
} -returnCodes 0 -result ""

eval destroy [winfo children .]
destroy {*}[winfo children .]

tcltest::cleanupTests

#*EOF*
Changes to tests/ttk/validate.test.
74
75
76
77
78
79
80


81
82
83


84
85
86
87


88
89
90


91
92
93
94
95


96
97
98


99
100
101
102


103
104
105


106
107
108
109
110


111
112
113


114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
74
75
76
77
78
79
80
81
82
83


84
85
86
87
88
89
90
91
92


93
94
95
96
97
98
99
100
101
102


103
104
105
106
107
108
109
110
111


112
113
114
115
116
117
118
119
120
121


122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137

138
139
140
141
142
143
144







+
+

-
-
+
+




+
+

-
-
+
+





+
+

-
-
+
+




+
+

-
-
+
+





+
+

-
-
+
+






-






+

-







    set ::vVals {}
    .e configure -validate focus
    .e insert end d
    set ::vVals
} -result {}

test validate-1.8 {entry widget validation - vmode focus} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .e
    # update necessary to process FocusIn event
    update
    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focus focusin}

test validate-1.9 {entry widget validation - vmode focus} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .
    # update necessary to process FocusOut event
    update
    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focus focusout}

.e configure -validate all
test validate-1.10 {entry widget validation - vmode all} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .e
    # update necessary to process FocusIn event
    update
    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} all focusin}

test validate-1.11 {entry widget validation} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .
    # update necessary to process FocusOut event
    update
    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} all focusout}
.e configure -validate focusin

test validate-1.12 {entry widget validation} -body {
    set ::vVals {}
    set timer [after 300 lappend ::vVals timeout]
    focus -force .e
    # update necessary to process FocusIn event
    update
    vwait ::vVals
    after cancel $timer
    set ::vVals
} -result {.e -1 -1 abcd abcd {} focusin focusin}

test validate-1.13 {entry widget validation} -body {
    set ::vVals {}
    focus -force .
    # update necessary to process FocusOut event
    update
    set ::vVals
} -result {}
.e configure -validate focuso

test validate-1.14 {entry widget validation} -body {
    set ::vVals {}
    focus -force .e
    # update necessary to process FocusIn event
    update
    set ::vVals
} -result {}

test validate-1.15 {entry widget validation} -body {
    focus -force .
    # update necessary to process FocusOut event
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248







-
+








### invalid state behavior
#

test validate-3.0 "Setup" -body {
    set ::E "123"
    ttk::entry .e \
    	-validatecommand {string is integer -strict %P} \
	-validatecommand {string is integer -strict %P} \
	-validate all \
	-textvariable ::E \
	;
    return [list [.e get] [.e state]]
} -result [list 123 {}]

test validate-3.1 "insert - valid" -body {
Changes to tests/unixButton.test.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
imageInit
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
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 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.
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

namespace eval ::_test_tmp {}

# ------------------------------------------------------------------------------
#  Proc ::_test_tmp::testInterp
# ------------------------------------------------------------------------------
87
88
89
90
91
92
93
94

95
96

97
98
99
100
101

102
103

104
105
106
107
108

109
110

111
112
113
114
115
116
117
118
119

120
121
122

123
124

125
126
127
128
129
130
131
132

133
134
135
136

137
138

139
140
141
142
143
144
145

146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174

175
176

177
178
179
180
181
182
183
184
185
186
187




188
189
190

191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216

217
218

219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235

236
237

238
239
240
241
242
243
244
245



246
247
248
249
250

251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280

281
282

283
284
285
286
287
288
289
290
291
292





293
294
295

296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320

321
322

323
324
325
326
327
328
329
330
331
332

333
334

335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358



359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386

387
388

389
390
391
392
393
394
395
396
397

398
399
400

401
402

403
404
405
406
407
408
409
410
411




412
413
414
415

416
417
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
444

445
446

447
448
449
450
451
452
453
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
87
88
89
90
91
92
93

94
95

96
97
98
99
100

101
102

103
104
105
106
107

108
109

110
111
112
113
114
115
116
117
118

119
120
121

122
123

124
125
126
127
128
129
130
131

132
133
134
135

136
137

138
139
140
141
142
143
144

145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173

174
175

176
177
178
179
180
181
182
183




184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215

216
217

218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234

235
236

237
238
239
240
241
242



243
244
245
246
247
248
249

250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279

280
281

282
283
284
285
286
287





288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319

320
321

322
323
324
325
326
327
328
329
330
331

332
333

334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355



356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385

386
387

388
389
390
391
392
393
394
395
396

397
398
399

400
401

402
403
404
405
406
407




408
409
410
411
412
413
414

415
416
417

418
419
420
421
422
423
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443

444
445

446
447
448
449
450
451




452
453
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







-
+

-
+




-
+

-
+




-
+

-
+








-
+


-
+

-
+







-
+



-
+

-
+






-
+




-
+














-
+








-
+

-
+







-
-
-
-
+
+
+
+


-
+















-
+









-
+

-
+








-
+







-
+

-
+





-
-
-
+
+
+




-
+


-
+













-
+












-
+

-
+





-
-
-
-
-
+
+
+
+
+


-
+













-
+










-
+

-
+









-
+

-
+









-
+











-
-
-
+
+
+



-
+













-
+









-
+

-
+








-
+


-
+

-
+





-
-
-
-
+
+
+
+



-
+


-
+













-
+











-
+

-
+





-
-
-
-
+
+
+
+



-
+


-
+













-
+











-
+

-
+





-
-
+
+



-
+




-
+













-
+










-
+

-
+





-
-
-
-
+
+
+
+



-
-
-
+
+
+


-
+













-
+













-
+

-
+







-
-
+
+



-
+




-
+















-
+












-
+

-
+





-
-
+
+



-
+



-
+


-
+













-
+











-
+

-
+





-
-
+
+







-
+














-
+












-
+

-
+



+


-
-
-
-
-
+
+
+
+
+





-
+











+


-
+














-
+

-
+



+


-
+




-
+





-
+











+


-
+












-
+

-
+



+


-
-
-
-
-
+
+
+
+
+








-
+











+


-
+



















-
+

-
+





-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
+













-
+













-
+

-
+





-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
+














-
+
















-
+

-
+






-
-
+
+


-
+


-
-
-
-
-
+
+
+
+
+




-
-
+
+
















-
+



-
+



-
+

-
+







-
+


-
+

-
+





-
-
+
+




-
+


-
-
-
-
-
+
+
+
+
+




-
-
+
+













-
+





-
+



-
+

-
+







-
+





-
+






-
-
+
+




-
-
-
-
-
-
+
+
+
+
+
+


-
+













-
+







    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
    unix
} -setup {
	deleteWindows
    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
    unix
} -setup {
	deleteWindows
    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
    unix nonPortable
} -setup {
	deleteWindows
    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
    deleteWindows
} -result 0
test unixEmbed-1.4 {TkpUseWindow procedure, inheriting colormap} -constraints {
	unix nonPortable
    unix nonPortable
} -setup {
	deleteWindows
    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
    deleteWindows
} -result 1

test unixEmbed-1.5 {TkpUseWindow procedure, creating Container records} -constraints {
	unix testembed notAqua
    unix testembed notAqua
} -setup {
	deleteWindows
    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 .]
	destroy {*}[winfo children .]
	toplevel .t -use $w
	list [testembed] [expr [lindex [lindex [testembed all] 0] 0] - $w]
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix testembed notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	toplevel .t2 -use $w2
	testembed
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix testembed
} -setup {
	deleteWindows
    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
    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
    unix testembed notAqua
} -setup {
	deleteWindows
    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 {*}[winfo children .]
	toplevel .t1 -use $w1
	testembed
    }
    destroy .f1
    update
    dobg {
	    testembed
	testembed
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        testembed
    }
    destroy .f1
    update
    child eval {
        testembed
    }
} -cleanup {
    deleteWindows
} -result {}
test unixEmbed-2.2 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
    unix testembed notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	testembed
	destroy .t1
	testembed
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
        testembed
        destroy .t1
        testembed
    }
} -cleanup {
    interp delete child
    deleteWindows
} -result {}
test unixEmbed-2.3 {EmbeddedEventProc procedure} -constraints {
	unix testembed notAqua
    unix testembed notAqua
} -setup {
	deleteWindows
    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
    unix testembed
} -setup {
	deleteWindows
    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
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	wm withdraw .t1
    }
    list $x [testembed]
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix
} -setup {
	deleteWindows
    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
    deleteWindows
} -result {200x200+0+0}
test unixEmbed-3.3 {ContainerEventProc procedure, disallow position changes} -constraints {
	unix notAqua
    unix notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1 -bd 2 -relief raised
	update
	wm geometry .t1 +30+40
    }
    update
    dobg {
	    wm geometry .t1
        wm geometry .t1
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	update
	wm geometry .t1 300x100+30+40
    }
    update
    dobg {
	    wm geometry .t1
        wm geometry .t1
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	    .t1 configure -width 300 -height 80
	.t1 configure -width 300 -height 80
    }
    update
    list [winfo width .f1] [winfo height .f1] [dobg {wm geometry .t1}]
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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}
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
	set x unmapped
	bind .t1 <Map> {set x mapped}
    }
    update
    dobg {
	    after 100
	    update
	    set x
	after 100
	update
	set x
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	    destroy .t1
	destroy .t1
    }
    update
    list $x [winfo exists .f1]
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	    .t1 configure -width 180 -height 100
	.t1 configure -width 180 -height 100
    }
    update
    dobg {
	    winfo geometry .t1
	winfo geometry .t1
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix testembed notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    set x [testembed]
    destroy .f1
    update
    list $x [testembed]
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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
	    bind .t1 <FocusIn> {lappend x "focus in %W"}
	    bind .t1 <FocusOut> {lappend x "focus out %W"}
	    set x {}
	destroy {*}[winfo children .]
	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
    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
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update
    dobg "set w1 [winfo id .f1]"
    dobg {
	eval destroy [winfo child .]
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    dobg {
	    after 200 {destroy .t1}
	after 200 {destroy .t1}
    }
    after 400
    focus -force .f1
    update
} -cleanup {
	deleteWindows
    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
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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
	    bind .t1 <FocusIn> {lappend x "focus in %W"}
	    bind .t1 <FocusOut> {lappend x "focus out %W"}
	    set x {}
	destroy {*}[winfo children .]
	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
    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
    update
    child alias w1 winfo id .f1
    child eval {
        destroy [winfo child .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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]
	destroy {*}[winfo children .]
	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
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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]
	destroy {*}[winfo children .]
	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
    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 .]
        destroy {*}[winfo children .]
        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
    unix notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    bind . <KeyPress> {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
	bind .t1 <KeyPress> {lappend y {key %A}}
	set y {}
	event generate .t1 <KeyPress> -keysym a
	set y
    }]
    update
    list $x $y
} -cleanup {
	deleteWindows
    bind . <Key> {}
    deleteWindows
    bind . <KeyPress> {}
} -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 .]
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
    }
    focus -force .
    bind . <Key> {lappend x {key %A %E}}
    bind . <KeyPress> {lappend x {key %A %E}}
    set x {}
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        bind .t1 <KeyPress> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym a
        event generate .t1 <KeyPress> -keysym a
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete child
    deleteWindows
    bind . <Key> {}
    bind . <KeyPress> {}
} -result {{{key a 1}} {}}
test unixEmbed-7.2 {TkpRedirectKeyEvent procedure, don't forward keystroke width} -constraints {
	unix notAqua
    unix notAqua
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    bind . <KeyPress> {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
	bind .t1 <KeyPress> {lappend y {key %A}}
	set y {}
	event generate .t1 <KeyPress> -keysym b
	set y
    }]
    update
    list $x $y
} -cleanup {
	deleteWindows
    bind . <Key> {}
    deleteWindows
    bind . <KeyPress> {}
} -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 .]
        destroy {*}[winfo children .]
        toplevel .t1 -use [w1]
    }
    update
    focus -force .f1
    update
    bind . <Key> {lappend x {key %A}}
    bind . <KeyPress> {lappend x {key %A}}
    set x {}
    set y [child eval {
        update
        bind .t1 <Key> {lappend y {key %A}}
        bind .t1 <KeyPress> {lappend y {key %A}}
        set y {}
        event generate .t1 <Key> -keysym b
        event generate .t1 <KeyPress> -keysym b
        set y
    }]
    update
    list $x $y
} -cleanup {
    interp delete child
    deleteWindows
    bind . <Key> {}
    bind . <KeyPress> {}
} -result {{} {{key b}}}

test unixEmbed-8.1 {TkpClaimFocus procedure} -constraints {
    unix notAqua failsOnUbuntu failsOnXQuarz
} -setup {
	deleteWindows
    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
	destroy {*}[winfo children .]
	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
	set x [list [focus]]
	update
	after 500
	update
	lappend x [focus]
    }] [focus]
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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]]
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
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







-
+




-
-
-
-
+
+
+
+


-
+




-
+

-
+









-
-
+
+



-
+











-
-
-
-
-
-
+
+
+
+
+
+


-
+













-
+













-
+





-

-
+

-
+


-
+


-
+





-
+

-
+

-
+


-
+









-
+

-
+











+

-
-
-
+
+
+
+
+
+
-
-
+

-
-
+
+
-
-
+

+
-
-
+
+

-


+
-
+

-





-
+







    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
	. configure -bd 2 -highlightthickness 2 -relief sunken
    }
    focus -force .f2
    update
    list [child eval {
	    focus .
	    set x [list [focus]]
	    update
	    lappend x [focus]
	focus .
	set x [list [focus]]
	update
	lappend x [focus]
    }] [focus]
} -cleanup {
	deleteWindows
    deleteWindows
} -result {{{} .} .f1}
catch {interp delete child}

test unixEmbed-9.1 {EmbedWindowDeleted procedure, check parentPtr} -constraints {
	unix testembed
    unix testembed
} -setup {
	deleteWindows
    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]
	destroy $w
	lappend x [testembed]
    }
    set x
} -cleanup {
	deleteWindows
    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]
	destroy {*}[winfo children .]
	toplevel .t1 -use $w1 -highlightthickness 2 -bd 2 -relief sunken
	set x {}
	lappend x [testembed]
	destroy .t1
	lappend x [testembed]
    }
} -cleanup {
	deleteWindows
    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 .]
        destroy {*}[winfo children .]
        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
    unix
} -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
    update
    wm geometry .t1 +40+50
    update idletasks
    update
    wm geometry .t1
} -cleanup {
	deleteWindows
    deleteWindows
} -result {150x80+0+0}
test unixEmbed-10.2 {geometry propagation in tkUnixWm.c/UpdateGeometryInfo} -constraints {
    unix failsOnUbuntu failsOnXQuarz
    unix
} -setup {
    deleteWindows
} -body {
    frame .f1 -container 1 -width 200 -height 50
    pack .f1
    update idletasks
    update
    toplevel .t1 -use [winfo id .f1] -width 150 -height 80
    update idletasks
    update
    wm geometry .t1 70x300+10+20
    update idletasks
    update
    wm geometry .t1
} -cleanup {
	deleteWindows
    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
    update
    toplevel .embed -use [winfo id .t.f] -bg green
    update idletasks
    update
    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 {
    set result {}
    toplevel .main
    set result {}
    pack [button .main.b -text "Main Button" \
	      -command {lappend result ".main.b"}] -padx 30 -pady 30
    update
    frame .main.f -container 1 -width 200 -height 200
    button .main.b -text "Main Button" -command {lappend result "pushed .main.b"}
    wm geometry .main 200x400+100+100
    pack .main.f -fill both
    pack .main.b -padx 30 -pady 30
    pack [frame .main.f -container 1 -width 200 -height 200] -fill both
    update idletasks
    update
    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
    button .embed.b -text "Emb Button" -command {lappend result "pushed .embed.b"}
    pack .embed.b -padx 30 -pady 30
    wm geometry .main 200x400+100+100
    update idletasks
    update
    focus -force .main
    update
    set x [expr {[winfo x .main ] + [winfo x .main.b] + 40}]
    set y [expr {[winfo y .main ] + [winfo y .main.b] + 38}]
    set x [expr {[winfo rootx .main.b] + [winfo width .main.b]/2}]
    set y [expr {[winfo rooty .main.b] + [winfo height .main.b]/2}]
    lappend result [winfo containing $x $y]
    after 200
    pressbutton $x $y
    update
    set x [expr {[winfo rootx .embed.b] + [winfo width .embed.b]/2}]
    set y [expr {$y + 80}]
    set y [expr {[winfo rooty .embed.b] + [winfo height .embed.b]/2}]
    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}
} -result {.main.b {pushed .main.b} .embed.b {pushed .embed.b}}


# 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
1
2
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 © 1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 by Scriptics Corporation.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
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
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99

100
101
102
103
104
105
106
84
85
86
87
88
89
90

91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+






-
+







	{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} {
	{x11 noExceed hasCourierNew failsOnUbuntu failsOnXQuarz} {
    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} {
	{x11 noExceed hasArial failsOnUbuntu failsOnXQuarz} {
    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-*-*-*-*-*-*-*-*-*-*-*-*}
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+







} {}
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} {
test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} {x11 haveCourier37Font} {
    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.

233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248

249
250
251

252
253
254
255
256
257
258
259
260

261
262

263
264
265
266
267
268

269
270
271

272
273
274
275
276
277
278

279
280
281
282

283
284
285
286

287
288
289
290

291
292
293
294

295
296
297
298
299
300
301
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246

247
248
249

250
251
252
253
254
255
256
257
258

259
260

261
262
263
264
265
266

267
268
269

270
271
272
273
274
275
276

277
278
279
280

281
282
283
284

285
286
287
288

289
290
291
292

293
294
295
296
297
298
299
300







-
+







-
+


-
+








-
+

-
+





-
+


-
+






-
+



-
+



-
+



-
+



-
+







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 {
test unixfont-8.1 {InitFont 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 {
test unixfont-8.2 {InitFont 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 {
test unixfont-8.3 {InitFont 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} {
test unixfont-8.4 {InitFont procedure: classify characters} {x11 failsOnUbuntu failsOnXQuarz} {
    set x 0
    incr x [font measure $courier "䀀"]   ;# 6
    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} x11 {
test unixfont-8.5 {InitFont 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} {
test unixfont-8.6 {InitFont 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 {
test unixfont-8.7 {InitFont 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 {
test unixfont-8.8 {InitFont 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 {
test unixfont-8.9 {InitFont 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 {
test unixfont-8.10 {InitFont 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 {
test unixfont-8.11 {InitFont 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"
Changes to tests/unixMenu.test.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
1
2
3
4
5


6
7
8
9
10
11
12
13
14





-
-
+
+







# 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.
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
eval tcltest::configure $argv
tcltest::loadTestedCommands

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
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24






-
+








+
+







# 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.
# 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.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

global longValue selValue selInfo

set selValue {}
set selInfo {}

proc handler {type offset count} {
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134

135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151

152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245

246
247
248
249
250
251

252
253
254
255
256
257
258
259
260
261

262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318

319
320
321

322
323
324
325
326
327
328

329
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344

345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366

367
368
369
370
371
372
373
374
375
376

377
378
379
380
381
382

383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135

136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152

153
154
155
156

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

199
200
201
202

203
204
205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313

314
315
316
317
318
319

320
321
322

323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338

339
340
341
342
343
344
345

346
347
348
349
350
351

352
353
354
355
356
357
358
359
360
361

362
363
364
365
366
367

368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427







-
+








-
+






-
+





-
+










-
+



-
+



















-
+




-
+
















-
+



-
+












-
+














-
+





-
+









-
+





-
+









-
+





-
+












-
+





-
+









-
+





-
+









-
+





-
+


-
+






-
+








-
+






-
+





-
+









-
+





-
+









-
+





-
+









-
+







-
+









-
+







-
+







    x11
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 über
    .e insert 0 \u00fcber
    .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
    x11 failsOnXQuarz
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 üф
        .e insert 0 \u00fc\u0444
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result ü?
} -result \u00fc?

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 selValue \u00fc\u0444
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal üф $x] [string length $x]
        list [string equal \u00fc\u0444 $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 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]üф[string repeat x 3999] $x] \
            [string repeat x 3999]\u00fc\u0444[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 selValue \u00fc\u0444
    set selInfo {}
    set result [dobg {
        set x [selection get -type COMPOUND_TEXT]
        list [string equal üф $x] [string length $x]
        list [string equal \u00fc\u0444 $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 insert 0 \u00fcber$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 insert 0 [string repeat x 3999]\u00fc
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]ü
} -result [string repeat x 3999]\u00fc

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 insert 0 \u00fc[string repeat x 3999]
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result ü[string repeat x 3999]
} -result \u00fc[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 insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
        .e selection range 0 end
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]ü[string repeat x 4000]
} -result [string repeat x 3999]\u00fc[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 insert 0 [string repeat x 3999]\u00fc
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]ü
} -result [string repeat x 3999]\u00fc

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 insert 0 \u00fc[string repeat x 3999]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result ü[string repeat x 3999]
} -result \u00fc[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 insert 0 [string repeat x 3999]\u00fc[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]
} -result [string repeat x 3999]\u00fc[string repeat x 4000]

test unixSelect-1.13 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    x11
    x11 failsOnXQuarz
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 überф
    .e insert 0 \u00fcber\u0444
    .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
    x11 failsOnXQuarz
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 üф
        .e insert 0 \u00fc\u0444
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result üф
} -result \u00fc\u0444

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 insert 0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat Ää 50]\n 21]
} -result [string repeat [string repeat \u00c4\u00e4 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 insert 0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
        .e selection range 0 end
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat Ää 50]\n 21]
} -result i[string repeat [string repeat \u00c4\u00e4 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]
        .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
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat Ää 50]\n 21]
} -result [string repeat [string repeat \u00c4\u00e4 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]
        .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
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat Ää 50]\n 21]
} -result i[string repeat [string repeat \u00c4\u00e4 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"
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
1
2
3
4



5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47




48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75




-
-
-
+
+
+








-
+

+
+
+
+
+
+
+
+
+
+
+
+


















-
-
-
-
+
+
+
+
+



+




+






-
+







# 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.
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

# Starting with macOS Ventura it became necessary to wait for windows to be restacked
# or to be raised after creation.

if {[tk windowingsystem] eq "aqua"} {
    proc restackDelay {} {
	after 200;
	update idletasks
    }
} else {
    proc restackDelay {} {}
}

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).
# On macOS windows are not allowed to overlap the menubar at the top of the
# screen or the dock.  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) and an x coordinate larger than the
# width of the dock, if it happens to be on the left.

if {[tk windowingsystem] eq "aqua"} {
    set mb [expr [menubarheight] + 1]
    set X  100
    set Y0 $mb
    set Y2 [expr $mb + 2]
    set Y5 [expr $mb + 5]
} else {
    set X  20
    set Y0 0
    set Y2 2
    set Y5 5
}

set i 1
foreach geom "+$Y0+80 +80+$Y0 +0+$Y0" {
foreach geom "+$X+80 +80+$Y0 +$X+$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
100
101
102
103
104
105
106
107

108
109
110

111
112
113
114

115
116
117
118
119
120
121
115
116
117
118
119
120
121

122
123
124

125
126
127
128

129
130
131
132
133
134
135
136







-
+


-
+



-
+







	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" {
foreach geom "+$X+80 +$X+40 +$X+$Y0" {
    test unixWm-4.$i {moving window while withdrawn} unix {
	wm withdraw .t
	update idletasks
	sleep 10
	wm geom .t $geom
	update idletasks
	wm deiconify .t
	update idletasks
	sleep 10
	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
199
200
201
202
203
204
205

206
207
208
209
210
211
212

213
214
215
216
217
218

219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







-
+






-
+





-
+






-
+







    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 geom .t +100+$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
} 180x150+100+$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
} 250x60+100+$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
} 170x140+100+$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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
243
244
245
246
247
248
249




250
251
252
253
254
255
256







-
-
-
-







    set w2 [winfo width .t]
    set h2 [winfo height .t]
    .t config -width 114 -height 261
    update
    list $width $height $w2 $h2 [wm geom .t]
} {0 0 230 110 114x261+10+10}

# I don't know why the wait below is needed, but without it the test
# fails under twm.
sleep 200

test unixWm-6.5 {window initially iconic} {unix nonPortable} {
    destroy .t
    toplevel .t -width 100 -height 30
    wm geometry .t +0+0
    wm title .t 2
    wm iconify .t
    update idletasks
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311







-
+







    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} {
test unixWm-8.4 {icon windows} {unix failsOnUbuntu failsOnXQuarz} {
    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
631
632
633
634
635
636
637
638

639
640
641
642
643
644
645
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656







-
+







    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} {
test unixWm-16.3 {Tk_WmCmd procedure, "deiconify" option} {unix failsOnUbuntu failsOnXQuarz} {
    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}

811
812
813
814
815
816
817
818

819
820
821
822
823
824
825
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836







-
+







	    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"} {
if {[tk windowingsystem] eq "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
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
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







-
-
+
+










-
+







    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} {
} {1 {can't iconify .t2: it is an icon for .t}}
test unixWm-23.5 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu failsOnXQuarz} {
    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} {
test unixWm-23.6 {Tk_WmCmd procedure, "iconify" option} {unix failsOnUbuntu failsOnXQuarz} {
    destroy .t2
    toplevel .t2
    wm geom .t2 -0+0
    update idletasks
    set result [winfo ismapped .t2]
    wm iconify .t2
    update idletasks
1222
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235
1236
1233
1234
1235
1236
1237
1238
1239

1240
1241
1242
1243
1244
1245
1246
1247







-
+







    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"} {
if {[tk windowingsystem] eq "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
1360
1361
1362
1363
1364
1365
1366
1367

1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
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
    wm geometry .t 200x100+100+$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"
} "20x20+100+$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
1432
1433
1434
1435
1436
1437
1438
1439

1440
1441
1442
1443
1444
1445
1446
1443
1444
1445
1446
1447
1448
1449

1450
1451
1452
1453
1454
1455
1456
1457







-
+







    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} {
test unixWm-42.1 {WrapperEventProc procedure, map and unmap events} {unix failsOnUbuntu failsOnXQuarz} {
    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"}
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
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







-
+
-

+







-
+
-

+







    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} {
test unixWm-44.7 {UpdateGeometryInfo procedure, computing position} {unix} {
    tkwait visibility .t
    wm overrideredirect .t 1
    tkwait visibility .t
    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} {
test unixWm-44.8 {UpdateGeometryInfo procedure, computing position} {unix} {
    tkwait visibility .t
    wm overrideredirect .t 1
    tkwait visibility .t
    update
    wm geometry .t -30+$Y2
    update
    list [winfo x .t] [winfo y .t]
} [list [expr [winfo screenwidth .t] - 110] $Y2]
destroy .t

1609
1610
1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622
1623
1620
1621
1622
1623
1624
1625
1626

1627
1628
1629
1630
1631
1632
1633
1634







-
+







    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} {
test unixWm-45.2 {UpdateSizeHints procedure} {unix testwrapper} {
    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
1648
1649
1650
1651
1652
1653
1654

1655
1656
1657
1658
1659
1660
1661
1662







-
+







    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} {
test unixWm-45.4 {UpdateSizeHints procedure, not resizable with menu} {testmenubar testwrapper} {
    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
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758







-
+







    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
} {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
1784
1785
1786
1787
1788
1789
1790
1791

1792
1793
1794
1795
1796
1797
1798
1795
1796
1797
1798
1799
1800
1801

1802
1803
1804
1805
1806
1807
1808
1809







-
+







    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"} {
if {[tk windowingsystem] eq "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} {
1816
1817
1818
1819
1820
1821
1822
1823
1824



1825
1826
1827
1828


1829

1830
1831
1832
1833
1834
1835
1836
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







-

+
+
+


-

+
+

+







	 [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
    wm geom .t +100+100
    update
    restackDelay
    toplevel .t2 -width 200 -height 100 -bg blue
    wm overrideredirect .t2 1
    wm geom .t2 +200+200
    tkwait visibility .t2
    wm geom .t2 +200+200
    update
    raise .t2
    restackDelay
    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]] \
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
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







-
+












-

+



-
+
+







        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]}]]
	[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
    wm geometry .t +100+100
    update
    interp create child
    load {} Tk child
    child eval {wm geometry . 200x200+100+100; tkwait visibility . ; update}
    child eval {wm geometry . 200x200+100+100; update}
    restackDelay
    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
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
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







-
+



-

+
+
+

-

+
+
+
+


-
+







    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} {
test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} {unix failsOnUbuntu failsOnXQuarz} {
    destroy .t
    destroy .t2
    toplevel .t -width 200 -height 200 -bg green
    wm geometry .t +0+0
    tkwait visibility .t
    update
    wm geometry .t +0+0
    update
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    tkwait visibility .t2
    update
    wm geometry .t2 +0+0
    update
    restackDelay
    set result [list [winfo containing 100 100]]
    wm iconify .t2
    update idletasks
    update
    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
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
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







-

+
+
+


-
+





-

+
-
+
+


+

-
+

+
+
-
+












+










+


+



-
+













+











+


-
+







    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
    wm geometry .t +0+0
    update
    restackDelay
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm geometry .t2 +0+0
    # This test assumes that .t2 is not mapped yet, but that is not really guaranteed.
    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
	tkwait visibility $w
	wm geometry $w +0+0
	wm geometry $w +100+100
	update
    }
    raise .t .t2
    restackDelay
    update
    set result [list [winfo containing 100 100]]
    set result [list [winfo containing 200 200]]
    lower .t3
    restackDelay
    sleep 10
    lappend result [winfo containing 100 100]
    lappend result [winfo containing 200 200]
} {.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
    tkwait visibility .t
    destroy .t2
    toplevel .t2 -width 200 -height 200 -bg red
    wm overrideredirect .t2 1
    wm geometry .t2 +0+0
    tkwait visibility .t2
    restackDelay

    # 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]]
    raise .t
    restackDelay
    lappend result [winfo containing $x $y]
    raise .t2
    restackDelay
    lappend result [winfo containing $x $y]
} {.t2 .t .t2}
# The mac won't put an overrideredirect window above the root,
if {[tk windowingsystem] == "aqua"} {
if {[tk windowingsystem] eq "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
    restackDelay
    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
    restackDelay
    lappend result [winfo containing $x $y]
} {.t2 .t3}
if {[tk windowingsystem] == "aqua"} {
if {[tk windowingsystem] eq "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}
2492
2493
2494
2495
2496
2497
2498
2499

2500
2501
2502
2503
2504
2505
2506
2524
2525
2526
2527
2528
2529
2530

2531
2532
2533
2534
2535
2536
2537
2538







-
+








#
# 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"} {
if {[tk windowingsystem] eq "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 {
Changes to tests/util.test.
1
2
3
4
5
6



7
8
9
10
11
12
13
1
2
3



4
5
6
7
8
9
10
11
12
13



-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

24
25
26
27
28
29
30
31

32
33
34

35
36
37

38
39
40
41
42
43
44
24
25
26
27
28
29
30

31
32
33

34
35
36

37
38
39
40
41
42
43
44







-
+


-
+


-
+







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"}
} -returnCodes error -result {wrong # args: should be ".l yview scroll number units|pages"}
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"}
} -returnCodes error -result {wrong # args: should be ".l yview scroll number units|pages"}
test util-1.6 {Tk_GetScrollInfo procedure} -body {
    .l yview scroll xyz units
} -returnCodes error -result {expected floating-point number but got "xyz"}
} -returnCodes error -result {expected integer 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
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68







-
+








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}
} -returnCodes error -result {bad argument "zips": must be units or pages}
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

Changes to tests/visual.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
1
2
3
4



5
6
7
8
9
10
11
12
13
14




-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

Changes to tests/visual_bb.test.
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33







-
+








# 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]]
    uplevel \#0 source -encoding utf-8 [file join [testsDirectory] $file]
    concat ""
    } {}
    incr testNum
}

# The following procedure is invoked to print the contents of a canvas:

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116







-
+









-
+









    .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> {
    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 <Button-1> {%W delete [%W find closest %x %y]}
    bind Canvas <1> {%W delete [%W find closest %x %y]}

    concat ""
} -result {}

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
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







# 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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands
imageInit
Changes to tests/winClipboard.test.
1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
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 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test

66
67
68
69
70
71
72
73

74
75
76
77
78

79
80
81
82
83
84
85

86
87
88
89


90
91
92
93
94
95
96
66
67
68
69
70
71
72

73
74
75
76
77

78
79
80
81
82
83
84

85
86
87
88

89
90
91
92
93
94
95
96
97







-
+




-
+






-
+



-
+
+








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"
    clipboard append "line 1\u00c7\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"]
} -result [list "line 1\u00c7\\nline 2" "line 1\u00c7\\nline 2"]

test winClipboard-1.6 {TkSelGetSelection & TkWinClipboardRender} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append "привет миф"
    clipboard append "\u043f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0444"
    list [selection get -selection CLIPBOARD] [testclipboard]
} -cleanup {
    clipboard clear
} -result [list "привет миф" "привет миф"]
} -result [list "\u043f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0444"\
              "\u043f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0444"]

test winClipboard-2.1 {TkSelUpdateClipboard reentrancy problem} -constraints {
    win testclipboard
} -setup {
    clipboard clear
} -body {
    clipboard append -type OUR_ACTION "action data"
Changes to tests/winDialog.test.
1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
1
2
3
4
5



6
7
8
9
10
11
12
13
14
15





-
-
-
+
+
+







# -*- 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 1998-1999 ActiveState Corporation.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

if {[testConstraint testwinevent]} {
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
157
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 "Привет"]
                     -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 "Привет" 0 "#ff9933"]
} -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 {}
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555







-
+







    }
    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 "ŧéŝŧ"]
    set dir [tcltest::makeDirectory "\u0167\u00e9\u015d\u0167"]
    unset -nocomplain x
    start {set x [tk_getSaveFile \
                      -initialdir $dir \
                      -initialfile "testfile" -title Foo]}
    then {
        Click 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
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







-
+
+
+
+
+
+
+
+
+
+
+
+











+
+
+
+







        }
    } finally {
        cd $cur
    }
    string equal $x [file join $dir testfile]
} -result 1

test winDialog-5.12.7 {tk_getOpenFile: initial directory: ~} -constraints {
test winDialog-5.12.7 {tk_getOpenFile: initial directory: ~} -setup {
    # Ensure there's at least one file in the home directory in CI environments
    set makeEmpty [expr {![llength [glob -nocomplain -type f -directory ~ *]]}]
    if {$makeEmpty} {
	for {set i 1} {$i < 1000} {incr i} {
	    # Technically a race condition...
	    set actualFilename [format "~/tkWinDialog5_12_7_%03d" $i]
	    if {![file exists $actualFilename]} break
	}
	close [open $actualFilename w]
    }
} -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]]
} -cleanup {
    if {$makeEmpty} {
	file delete $actualFilename
    }
} -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
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







-
+







    }
    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 dir [tcltest::makeDirectory "\u0167\u00e9\u015d\u0167"]
    set path [tcltest::makeFile "" testfile $dir]
    unset -nocomplain x
    start {set x [tk_getOpenFile \
                      -initialdir $dir \
                      -initialfile "testfile" -title Foo]}
    then {
        Click ok
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







-
+







    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 {••••}}}}]}
    start {set x [catch {tk_getSaveFile -filetypes {{"foo" .foo {\u2022\u2022\u2022\u2022}}}}]}
    then {
        Click cancel
    }
    return $x
} -result 0


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
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







-
+







-
+













test winDialog-10.9 {Tk_FontchooserObjCmd: -title} -constraints {
    nt testwinevent
} -setup {
    array set a {text failed}
} -body {
    start {
        tk fontchooser configure -command ApplyFont \
            -title  "Привет"
            -title  "\u041f\u0440\u0438\u0432\u0435\u0442"
        tk fontchooser show
    }
    then {
        array set a [testgetwindowinfo $::tk_dialog]
        Click cancel
    }
    set a(text)
} -result "Привет"
} -result "\u041f\u0440\u0438\u0432\u0435\u0442"

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
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 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.
# Copyright (c) 1996-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99







-
+








-
+








-
+







    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}}
} -result {{Times New Roman} {Times New Roman} {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}}
} -result {{Courier New} {Courier New} {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}
} -result {Arial Arial Arial}
test winfont-2.10 {TkpGetFontFromAttributes procedure: fallback} -constraints {
    win
} -body {
    # No way to get it to fail! Any font name is acceptable.
} -result {}


350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374

375
376
377
378
379

380
381
382
383
384
385
386
387
388
389
390
391
392
350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373

374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390
391
392







-
+











-
+




-
+




-
+













    .t.l config -text "a"
    update
} -cleanup {
    destroy .t.l
} -result {}


test winfont-7.1 {AllocFont procedure: use old font} -constraints win -setup {
test winfont-7.1 {InitFont 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 {
test winfont-7.2 {InitFont 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 {
test winfont-7.3 {InitFont 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 {
test winfont-7.4 {InitFont procedure: extract info from textmetric} -constraints {
    win
} -body {
    font metric systemfixed -fixed
} -result 1

# cleanup
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/winMenu.test.
1
2
3
4
5
6
7


8
9
10
11
12
13
14
1
2
3
4
5


6
7
8
9
10
11
12
13
14





-
-
+
+







# 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.
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

Changes to tests/winMsgbox.test.
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







# This file is a Tcl script to test the Windows specific message box
#
# Copyright © 2007 Pat Thoyts <patthoyts@users.sourceforge.net>
# Copyright (c) 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}]
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234

235
236
237
238
239
240
241
220
221
222
223
224
225
226

227
228
229
230
231
232
233

234
235
236
237
238
239
240
241







-
+






-
+







    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-2.2 [pid]"
    set message "Поиск страниц"
    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 "Поиск страниц"]
} -result [list ok "\u041f\u043e\u0438\u0441\u043a\u0020\u0441\u0442\u0440\u0430\u043d\u0438\u0446"]

test winMsgbox-2.4 {tk_messageBox message (empty)} -constraints {
    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
272
273
274
275
276
277
278
279
280


281
282
283
284
285
286
287

288
289
290
291
292
293
294
295
296
297
298
299
300
272
273
274
275
276
277
278


279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294
295
296
297
298
299
300







-
-
+
+






-
+













    win getwindowinfo
} -setup {
    wm iconify .
    unset -nocomplain info
} -body {
    global windowInfo
    set title "winMsgbox-3.1 [pid]"
    set message "Поиск"
    set detail "страниц"
    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 "Поиск\n\nстраниц"]
} -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
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.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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.
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
1
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 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.
# Copyright (c) 1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

test winWm-1.1 {TkWmMapWindow} -constraints win -setup {
    destroy .t
} -body {
    toplevel .t
    wm override .t 1
    wm geometry .t +0+0
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
276
277
278
279
280
281
282

283
284
285
286

287
288
289
290
291
292
293
294







-




-
+







    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 {
    destroy .t
} -returnCodes error -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
} -returnCodes error -result {bad attribute "-foo": must be -alpha, -transparentcolor, -disabled, -fullscreen, -toolwindow, or -topmost}

test winWm-6.4 {wm attributes -alpha} -constraints win -setup {
    destroy .t
} -body {
    # Expect this to return all 1.0 {} on pre-2K/XP
    toplevel .t
    set res [wm attributes .t -alpha]
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
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 <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
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 <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
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 {
test winWm-9.2 "check wm forget for unmapped parent (#3205464,#2967911)" -constraints {failsOnUbuntu failsOnXQuarz} -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
Changes to tests/window.test.
1
2
3
4
5


6
7
8
9
10
11
12
1
2
3


4
5
6
7
8
9
10
11
12



-
-
+
+







# 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.
# Copyright (c) 1995 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands
namespace import ::tk::test::loadTkCommand
259
260
261
262
263
264
265
































266
267
268
269
270
271
272
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    } else {
        set error 0
    }
    removeFile script
    list $error $msg
} -result {0 YES}

test window-2.12 {Test for ticket [9b6065d1fd] - restore Tcl [update] command} -constraints {
    unixOrWin
} -body {
    set code [loadTkCommand]
    append code {
	after 1000 {set forever 1}
	after 100 {destroy .}
	after 200 {catch bell msg; puts "ringing the bell -> $msg"}
	after 250 {update idletasks}
	after 300 {update}
	puts "waiting"
	vwait forever
	puts "done waiting"
	catch {bell} msg
	puts "bell -> $msg"
	catch update msg
	puts "update -> $msg"
    }
    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 {waiting
ringing the bell -> can't invoke "bell" command: application has been destroyed
done waiting
bell -> can't invoke "bell" command: application has been destroyed
update -> }}


test window-3.1 {Tk_MakeWindowExist procedure, stacking order and menubars} -constraints {
    unix testmenubar
} -setup {
    destroy .t
} -body {
    toplevel .t -width 300 -height 200
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384







+









    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:
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
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 "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.
# Copyright (c) 1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
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:
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304







-
+







} -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 {
test winfo-9.4 {"winfo viewable" command} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    wm iconify .
    winfo viewable .
} -cleanup {
    wm deiconify .
} -result 0
test winfo-9.5 {"winfo viewable" command} -setup {
    deleteWindows
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+







        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"} {
if {[tk windowingsystem] eq "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 {
Changes to tests/wm.test.
1
2
3
4
5
6
7



8
9
10
11
12
13
14
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.
# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
23
24
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 failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
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
    after 250;
    update idletasks
    update
}

# How to carry out a small delay while processing events

proc eventDelay {{delay 200}} {
    after $delay "set done 1" ; vwait done
}
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
124
125
126
127
128
129
130


131

132
133
134
135
136


137

138
139
140
141
142
143
144
145







-
-

-
+




-
-

-
+









### wm attributes ###
test wm-attributes-1.1 {usage} -returnCodes error -body {
    wm attributes
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-attributes-1.2.1 {usage} -constraints win -returnCodes error -body {
    # This is the wrong error to output - unix has it right, but it's
    # not critical.
    wm attributes . _
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
} -result {bad attribute "_": must be -alpha, -transparentcolor, -disabled, -fullscreen, -toolwindow, or -topmost}
test wm-attributes-1.2.2 {usage} -constraints win -returnCodes error -body {
    wm attributes . -alpha 1.0 -disabled
} -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.3 {usage} -constraints win -returnCodes error -body {
    # This is the wrong error to output - unix has it right, but it's
    # not critical.
    wm attributes . -to
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
} -result {bad attribute "-to": must be -alpha, -transparentcolor, -disabled, -fullscreen, -toolwindow, or -topmost}
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}

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
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







-
+







-
+









-
-
+
+








-
+




-
-
+
+







    wm deiconify .embed
} -returnCodes error -cleanup {
    destroy .t.f .embed
} -result {can't deiconify .embed: it is an embedded window}

deleteWindows
test wm-deiconify-2.1 {a window that has never been mapped\
        should not be mapped by a call to deiconify} -body {
	should not be mapped by a call to deiconify} -body {
    toplevel .t
    wm deiconify .t
    winfo ismapped .t
} -cleanup {
    deleteWindows
} -result 0
test wm-deiconify-2.2 {a window that has already been\
        mapped should be mapped by deiconify} -body {
	mapped should be mapped by deiconify} -body {
    toplevel .t
    update idletasks
    wm withdraw .t
    wm deiconify .t
    winfo ismapped .t
} -cleanup {
    deleteWindows
} -result 1
test wm-deiconify-2.3 {geometry for an unmapped window\
        should not be calculated by a call to deiconify,\
        it should be done at idle time} -setup {
	should not be calculated by a call to deiconify,\
	it should be done at idle time} -setup {
    set results {}
} -body {
    toplevel .t -width 200 -height 200
    lappend results [wm geometry .t]
    wm deiconify .t
    lappend results [wm geometry .t]
    update idletasks
    lappend results [lindex [split \
        [wm geometry .t] +] 0]
	[wm geometry .t] +] 0]
} -cleanup {
    deleteWindows
} -result {1x1+0+0 1x1+0+0 200x200}
test wm-deiconify-2.4 {invoking destroy after a deiconify\
        should not result in a crash because of a callback\
        set on the toplevel} -body {
	should not result in a crash because of a callback\
	set on the toplevel} -body {
    toplevel .t
    wm withdraw .t
    wm deiconify .t
    destroy .t
    update
} -cleanup {
    deleteWindows
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
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







-
+









-
+









-
+

-
+







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"}
} -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}
} -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}
} -result {can't iconify .t2: it is an embedded window}

test wm-iconify-3.1 {iconify behavior} -constraints failsOnUbuntu -body {
test wm-iconify-3.1 {iconify behavior} -constraints {failsOnUbuntu failsOnXQuarz} -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]
876
877
878
879
880
881
882
883

884
885
886

887
888
889
890
891
892
893
872
873
874
875
876
877
878

879
880
881
882
883
884
885
886
887
888
889
890







-
+



+







} -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 *}
} -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
943
944
945
946
947
948
949


950
951
952
953
954
955
956
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955







+
+







    wm iconwindow .t2 .icon
    wm iconwindow .t .icon
} -returnCodes error -cleanup {
    destroy .t2 .icon
} -result {.icon is already an icon for .t2}

test wm-iconwindow-2.1 {setting and reading values} -setup {
    # without this macOS crashes for unknown reasons
    wm iconwindow .t {}
    destroy .icon
    set result {}
} -body {
    lappend result [wm iconwindow .t]
    toplevel .icon -width 50 -height 50 -bg green
    wm iconwindow .t .icon
    lappend result [wm iconwindow .t]
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
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







-
+










-
+












-
+







    expr {($t_width <= $s_width) && ($t_height <= $s_height)}
} -cleanup {
    destroy .t
} -result 1

destroy .t
test wm-maxsize-2.1 {setting the maxsize to a value smaller\
        than the current size will resize a toplevel} -body {
	than the current size will resize a toplevel} -body {
    toplevel .t -width 300 -height 300
    update
    wm maxsize .t 200 150
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} -cleanup {
    destroy .t
} -result {200 150}
test wm-maxsize-2.2 {setting the maxsize to a value smaller\
        than the current size will resize a gridded toplevel} -body {
	than the current size will resize a gridded toplevel} -body {
    toplevel .t
    wm grid .t 0 0 50 50
    wm geometry .t 6x6
    update
    wm maxsize .t 4 3
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} -cleanup {
    destroy .t
} -result {4 3}
test wm-maxsize-2.3 {attempting to resize to a value\
        bigger than the current maxsize will set it to the max size} -body {
	bigger than the current maxsize will set it to the max size} -body {
    toplevel .t -width 200 -height 200
    wm maxsize .t 300 250
    update
    wm geom .t 400x300
    update
    lrange [split [wm geom .t] x+] 0 1
} -cleanup {
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
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







-
+










-
+












-
+







    wm minsize .t2 300 200
    wm minsize .t2
} -cleanup {
    destroy .t2
} -result {300 200}

test wm-minsize-2.1 {setting the minsize to a value larger\
        than the current size will resize a toplevel} -body {
	than the current size will resize a toplevel} -body {
    toplevel .t -width 200 -height 200
    update
    wm minsize .t 400 300
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} -cleanup {
    destroy .t
} -result {400 300}
test wm-minsize-2.2 {setting the minsize to a value larger\
        than the current size will resize a gridded toplevel} -body {
	than the current size will resize a gridded toplevel} -body {
    toplevel .t
    wm grid .t 1 1 50 50
    wm geom .t 4x4
    update
    wm minsize .t 8 8
    # UpdateGeometryInfo invoked at idle
    update
    lrange [split [wm geom .t] x+] 0 1
} -cleanup {
    destroy .t
} -result {8 8}
test wm-minsize-2.3 {attempting to resize to a value\
        smaller than the current minsize will set it to the minsize} -body {
	smaller than the current minsize will set it to the minsize} -body {
    toplevel .t -width 400 -height 400
    wm minsize .t 300 300
    update
    wm geom .t 200x200
    update
    lrange [split [wm geom .t] x+] 0 1
} -cleanup {
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
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







+













+
-
-
+
+
+
+
+
+
+


+


-
+
+


-
+







} -cleanup {
    destroy .t
} -returnCodes error -result {window ".t" isn't mapped}
deleteWindows

test wm-stackorder-2.1 {stacking order} -body {
    toplevel .t ; update
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {. .t}
test wm-stackorder-2.2 {stacking order} -body {
    toplevel .t ; update
    raise .
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t
} -result {.t .}
test wm-stackorder-2.3 {stacking order} -body {
    set res {}
    toplevel .t ; update
    toplevel .t2 ; update
    toplevel .t
    tkwait visibility .t
    raiseDelay
    toplevel .t2
    tkwait visibility .t2
    raiseDelay
    lappend res [wm stackorder .] 
    raise .
    raiseDelay
    lappend res [wm stackorder .] 
    raise .t2
    raiseDelay
    wm stackorder .
    lappend res [wm stackorder .]
    set res
} -cleanup {
    destroy .t .t2
} -result {.t . .t2}
} -result {{. .t .t2} {.t .t2 .} {.t . .t2}}
test wm-stackorder-2.4 {stacking order} -body {
    toplevel .t ; update
    toplevel .t2 ; update
    raise .
    lower .t2
    raiseDelay
    wm stackorder .
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
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







+















-
+

+

+

+








+







    raiseDelay
    wm stackorder .parent
} -cleanup {
    deleteWindows
} -result {.parent.child2 .parent.child1 .parent}
test wm-stackorder-2.6 {stacking order: non-toplevel widgets ignored} -body {
    toplevel .t1
    raiseDelay
    button .t1.b
    pack .t1.b
    update
    wm stackorder .
} -cleanup {
    destroy .t1
} -result {. .t1}
test wm-stackorder-2.7 {stacking order: no children returns self} -setup {
    deleteWindows
} -body {
    wm stackorder .
} -result {.}

deleteWindows

test wm-stackorder-3.1 {unmapped toplevel} -constraints failsOnUbuntu -body {
test wm-stackorder-3.1 {unmapped toplevel} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t1 ; update
    raiseDelay
    toplevel .t2 ; update
    raiseDelay
    wm iconify .t1
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t2}
test wm-stackorder-3.2 {unmapped toplevel} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
    wm withdraw .t2
    raiseDelay
    wm stackorder .
} -cleanup {
    destroy .t1 .t2
} -result {. .t1}
test wm-stackorder-3.3 {unmapped toplevel} -body {
    toplevel .t1 ; update
    toplevel .t2 ; update
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464






1465

1466
1467
1468
1469
1470
1471
1472
1468
1469
1470
1471
1472
1473
1474



1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489







-
-
-
+
+
+
+
+
+

+







    toplevel .t1.t2 ; update
    wm withdraw .t1
    wm stackorder .t1
} -cleanup {
    destroy .t1
} -result {.t1.t2}
test wm-stackorder-3.6 {unmapped toplevel} -body {
    toplevel .t1 ; update
    toplevel .t1.t2 ; update
    toplevel .t1.t2.t3 ; update
    toplevel .t1
    tkwait visibility .t1
    toplevel .t1.t2
    tkwait visibility .t1.t2
    toplevel .t1.t2.t3
    tkwait visibility .t1.t2.t3
    wm withdraw .t1.t2
    raiseDelay
    wm stackorder .t1
} -cleanup {
    destroy .t1
} -result {.t1 .t1.t2.t3}
test wm-stackorder-3.7 {unmapped toplevel, mapped children returned} -body {
    toplevel .t1 ; update
    toplevel .t1.t2 ; update
1494
1495
1496
1497
1498
1499
1500
1501


1502
1503
1504

1505
1506
1507
1508
1509
1510
1511
1511
1512
1513
1514
1515
1516
1517

1518
1519
1520
1521

1522
1523
1524
1525
1526
1527
1528
1529







-
+
+


-
+







    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
    toplevel .t
    tkwait visibility .t
    raise .
    raiseDelay
    wm stackorder .t isa .
    wm stackorder .t isabove .
} -cleanup {
    destroy .t
} -result 0
test wm-stackorder-4.4 {wm stackorder isabove|isbelow} -body {
    toplevel .t ; update
    raise .
    raiseDelay
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
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







-

+










-

+








-
+

-

+









-
+

+

-
+







    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
    tkwait visibility .t
    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
    tkwait visibility .t
    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 {
	can be explicitly lowered} -body {
    toplevel .t
    tkwait visibility .t
    wm overrideredirect .t 1
    tkwait visibility .t
    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 {
	 stacking order} -body {
    toplevel .real -container 1
    raiseDelay
    toplevel .embd -bg blue -use [winfo id .real]
    update
    raiseDelay
    wm stackorder .
} -cleanup {
    deleteWindows
} -result {. .real}

stdWindow

1596
1597
1598
1599
1600
1601
1602
1603

1604
1605
1606
1607
1608
1609
1610
1615
1616
1617
1618
1619
1620
1621

1622
1623
1624
1625
1626
1627
1628
1629







-
+







} -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?"}
} -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
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
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







-
+





-
+









-
+






-
+







    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}
} -result {can't make ".icon" a master: 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}
} -result {setting ".top" as master creates a transient/master cycle}
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}
} -result {setting ".t3" as master creates a transient/master cycle}
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}
} -result {setting ".top" as master creates a transient/master cycle}

test wm-transient-2.1 {basic get/set of toplevel} -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    lappend results [wm transient .subject]
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
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







-
+











-
+












-
+

















-
+











-
+













-
+

















-
+


















-
+











-
+










-
+














-
+







    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 {
	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 {
	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 {
	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 {
	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 {
	is withdrawn if toplevel is iconic} -constraints {failsOnUbuntu failsOnXQuarz} -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 {
	does a withdraw/deiconify on the transient} -constraints {failsOnUbuntu failsOnXQuarz} -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 {
	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 {
	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 {
	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 {
	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 {
	state changes in the toplevel} -setup {
    set results [list]
} -body {
    toplevel .top
    toplevel .subject
    update
    wm transient .subject .top
    wm withdraw .subject
1849
1850
1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1868
1869
1870
1871
1872
1873
1874

1875
1876
1877
1878
1879
1880
1881
1882







-
+







    # 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 {
	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
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
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







-
+












-
+
















-
+







}
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 .t2		;# caused panic in 8.4b1
    destroy .t1
    destroy .transient
} -cleanup {
    deleteWindows
}
test wm-transient-7.5 {Reassign transient, destroy transient} -body {
    toplevel .t1
    toplevel .t2
    toplevel .transient
    wm transient .transient .t1
    wm transient .transient .t2
    destroy .transient
    destroy .t2 	;# caused panic in 8.4b1
    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
    raise .t1; raiseDelay; update
    lappend result [lsearch -all -inline -glob [wm stackorder .] ".t?"]
} -cleanup {
    deleteWindows
} -result {0 0 1 1 {.t1 .t2}}


### wm state ###
2002
2003
2004
2005
2006
2007
2008
2009

2010
2011
2012
2013
2014
2015
2016
2017

2018
2019
2020
2021
2022
2023
2024
2021
2022
2023
2024
2025
2026
2027

2028
2029
2030
2031
2032
2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
2043







-
+







-
+







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 {
test wm-state-2.8 {state change after map} -constraints {failsOnUbuntu failsOnXQuarz} -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 {
test wm-state-2.9 {state change after map} -constraints {failsOnUbuntu failsOnXQuarz} -body {
    toplevel .t
    update
    wm iconify .t
    wm state .t
} -cleanup {
    deleteWindows
} -result {iconic}
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
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







-
-
-
-
-









-
+


-
+


-
+







} -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
    update
    lappend res [winfo manager .f]
    wm manage .f
    doUpdate
    update
    lappend res [winfo manager .f]
    wm forget .f
    doUpdate
    update
    lappend res [winfo manager .f]
} -cleanup {
    destroy .l .f.b .f
    unset res
} -result {pack {} wm {}}

# FIXME:
Changes to tests/xmfbox.test.
1
2
3
4
5
6
7
8
9


10
11
12
13
14
15
16
1
2
3
4
5
6
7


8
9
10
11
12
13
14
15
16







-
-
+
+







# 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.
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 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
Changes to unix/Makefile.in.
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122







-
+















-
+







# 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@
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

# The directory containing the platform specific Tcl sources and headers
# appropriate for this version of Tk:
TCL_PLATFORM_DIR	= $(TCLDIR)/unix

# The directory containing the Tcl library archive file appropriate
# for this version of Tk:
TCL_BIN_DIR		= @TCL_BIN_DIR@

# The linker flags needed to link in the Tcl library (ex: -ltcl8.2)
# The linker flags needed to link in the Tcl library (ex: -ltcl8.6)
TCL_LIB_FLAG		= @TCL_LIB_FLAG@

# Flag, 1: we're building a shared lib, 0 we're not
TK_SHARED_BUILD		= @TK_SHARED_BUILD@

# Subdirectory of $(libdir) containing the pkgIndex.tcl file for loadable Tk
TK_PKG_DIR		= @TK_PKG_DIR@
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199







-
+







# XStringToKeysym is plenty fast, so you needn't define REDO_KEYSYM_LOOKUP.
KEYSYM_FLAGS		=
#KEYSYM_FLAGS		= -DREDO_KEYSYM_LOOKUP

# 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	=
#NO_DEPRECATED_FLAGS	= -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED

# Some versions of make, like SGI's, use the following variable to
# determine which shell to use for executing commands:
SHELL			= @SHELL@

# BUILD_TCLSH is the fully qualified path name of the tclsh shell
215
216
217
218
219
220
221
222
223


224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
215
216
217
218
219
220
221


222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239







-
-
+
+








-
+







TKTEST_EXE		= tktest${EXE_SUFFIX}

# 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_STRIP_PROGRAM   = -s
INSTALL_STRIP_LIBRARY   = -S -x
INSTALL_STRIP_PROGRAM	= strip
INSTALL_STRIP_LIBRARY	= strip -x

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.
# 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@ -DBUILD_tk

# To enable support for stubs in Tcl.
STUB_LIB_FILE		= @TK_STUB_LIB_FILE@

264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
295







-
+
















-
+








# 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
# 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	= ${LIB_RUNTIME_DIR}
DYLIB_INSTALL_DIR	= $(libdir)

# 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)

354
355
356
357
358
359
360
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373


374
375

376
377
378
379
380
381
382







-
+












-
-
+
+
-







	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
	tkImgPhoto.o tkImgPhInstance.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 \
	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
	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 \
393
394
395
396
397
398
399
400
401
402
403
404
405






406
407
408


409
410
411
412
413
414
415
392
393
394
395
396
397
398






399
400
401
402
403
404



405
406
407
408
409
410
411
412
413







-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+







	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 \
	tkMacOSXEvent.o tkMacOSXFileTypes.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 \
	tkMacOSXWm.o tkMacOSXXStubs.o \
	tkFileFilter.o tkMacWinMenu.o tkPointer.o tkUnix3d.o tkUnixScale.o \
	xcolors.o xdraw.o xgc.o ximage.o xutil.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

OBJS =  $(GENERIC_OBJS) $(WIDG_OBJS) $(CANV_OBJS) $(IMAGE_OBJS) $(TEXT_OBJS) \
	$(STUB_OBJS) $(TTK_OBJS) \
	$(@TK_WINDOWINGSYSTEM@_OBJS) @PLAT_OBJS@
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

454

455
456
457
458
459
460
461
462







-


















-

-
+







	$(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)/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
520
521
522
523
524
525
526
527
528


529
530
531
532
533
534
535
516
517
518
519
520
521
522


523
524
525
526
527
528
529
530
531







-
-
+
+







AQUA_SRCS = \
	$(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)/tkMacOSXFont.c $(MAC_OSX_DIR)/tkMacOSXFileTypes.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 \
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
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







-
+
+




















-
+





+
+
+
+
+








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
X11_PRIVATE_HDRS = $(UNIX_DIR)/tkUnixPort.h $(UNIX_DIR)/tkUnixInt.h $(GENERIC_DIR)/tkIntXlibDecls.h \
	$(UNIX_DIR)/tkUnixDefault.h

# Currently private, eventually public
TTK_HDRS = $(TTK_DIR)/ttkTheme.h $(TTK_DIR)/ttkDecls.h

PUBLIC_HDRS = $(GENERIC_DIR)/tk.h $(GENERIC_DIR)/tkDecls.h \
	$(GENERIC_DIR)/tkPlatDecls.h $(@TK_WINDOWINGSYSTEM@_HDRS)

# The private headers we want installed for install-private-headers
PRIVATE_HDRS = $(GENERIC_DIR)/tkInt.h $(GENERIC_DIR)/tkIntDecls.h \
	$(GENERIC_DIR)/tkIntPlatDecls.h $(GENERIC_DIR)/tkPort.h \
	$(TTK_HDRS) $(@TK_WINDOWINGSYSTEM@_PRIVATE_HDRS)

DEMOPROGS = browse hello ixset rmt rolodex square tcolor timer widget

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
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}
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
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







-
+












-
+







-
-
+
+







	@echo ${OBJS}
# This targets actually build the objects needed for the lib in the above
# case
objs: ${OBJS}


${WISH_EXE}: $(TK_STUB_LIB_FILE) $(WISH_OBJS) $(TK_LIB_FILE) @APP_RSRC_FILE@
	${CC} ${CFLAGS} ${LDFLAGS} $(WISH_OBJS) @TK_BUILD_LIB_SPEC@ \
	${CC} ${CFLAGS} $(WISH_OBJS) @TK_BUILD_LIB_SPEC@ ${LDFLAGS} \
		$(WISH_LIBS) $(CC_SEARCH_FLAGS) -o ${WISH_EXE}

# Resetting the LIB_RUNTIME_DIR below is required so that
# the generated tktest executable gets the build directory
# 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) \
	${CC} ${CFLAGS} $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ ${LDFLAGS} $(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} \
# 	${CC} ${CFLAGS} test.o tkTest.o tkSquare.o \
# 		@TK_BUILD_LIB_SPEC@ ${LDFLAGS} ${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:
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
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_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \
		$(INSTALL_DEMO_TARGETS) $(INSTALL_EXTRA_TARGETS)

install: $(INSTALL_TARGETS)

install-strip:
	$(MAKE) $(INSTALL_TARGETS) \
		INSTALL_PROGRAM="$(INSTALL_PROGRAM) ${INSTALL_STRIP_PROGRAM}" \
		INSTALL_LIBRARY="$(INSTALL_LIBRARY) ${INSTALL_STRIP_LIBRARY}"
		INSTALL_PROGRAM="STRIPPROG='${INSTALL_STRIP_PROGRAM}' $(INSTALL_PROGRAM) -s" \
		INSTALL_LIBRARY="STRIPPROG='${INSTALL_STRIP_LIBRARY}' $(INSTALL_LIBRARY) -s"

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";\
	    echo "if {![package vsatisfies [package provide Tcl] 8.6.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)]] Tk]";\
	    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)]] Tk]";\
	    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]] Tk]";\
	    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}.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)/"; \
898
899
900
901
902
903
904

905
906


907
908
909
910

911
912
913
914
915
916
917
898
899
900
901
902
903
904
905
906

907
908
909
910
911

912
913
914
915
916
917
918
919







+

-
+
+



-
+








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
		errors ${WISH_EXE} $(TKTEST_EXE) lib.exp Tk *.rsrc \
		 *.zip

distclean: clean
	rm -rf Makefile config.status config.cache config.log tkConfig.sh \
		tkConfig.h *.plist Tk.framework tk.pc
		tkConfig.h *.plist Tk.framework tk.pc tkUuid.h

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).
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-















-
-
+
+








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
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkStyle.c

tkUtil.o: $(GENERIC_DIR)/tkUtil.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkUtil.c

tkVisual.o: $(GENERIC_DIR)/tkVisual.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkVisual.c

tkWindow.o: $(GENERIC_DIR)/tkWindow.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkWindow.c
tkWindow.o: $(GENERIC_DIR)/tkWindow.c tkUuid.h
	$(CC) -c $(CC_SWITCHES) -I. $(GENERIC_DIR)/tkWindow.c

tkButton.o: $(GENERIC_DIR)/tkButton.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkButton.c

tkEntry.o: $(GENERIC_DIR)/tkEntry.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkEntry.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
1166
1167
1168
1169
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







-
-
-









-
-
-









-
+








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
tkTest.o: $(GENERIC_DIR)/tkTest.c tkUuid.h
	$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tkTest.c

tkText.o: $(GENERIC_DIR)/tkText.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkText.c

tkTextBTree.o: $(GENERIC_DIR)/tkTextBTree.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTextBTree.c
1189
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199
1200
1201
1202
1203
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1173







-
+







tkStubInit.o: $(GENERIC_DIR)/tkStubInit.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkStubInit.c

# Stub library binaries, these must be compiled for use in a shared library
# even though they will be placed in a static archive

tkStubLib.o: $(GENERIC_DIR)/tkStubLib.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkStubLib.c
	$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ $(GENERIC_DIR)/tkStubLib.c

tkUndo.o: $(GENERIC_DIR)/tkUndo.c
	$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkUndo.c

tkUnix.o: $(UNIX_DIR)/tkUnix.c
	$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnix.c

1298
1299
1300
1301
1302
1303
1304



1305
1306
1307
1308
1309
1310
1311
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284







+
+
+








tkMacOSXEntry.o: $(MAC_OSX_DIR)/tkMacOSXEntry.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXEntry.c

tkMacOSXEvent.o: $(MAC_OSX_DIR)/tkMacOSXEvent.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXEvent.c

tkMacOSXFileTypes.o: $(MAC_OSX_DIR)/tkMacOSXFileTypes.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/tkMacOSXFileTypes.c

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
1459
1460
1461
1462
1463
1464
1465
1466

1467
1468
1469
1470
1471
1472
1473
1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442
1443
1444
1445
1446







-
+







ttkState.o: $(TTK_DIR)/ttkState.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkState.c

ttkStubInit.o: $(TTK_DIR)/ttkStubInit.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkStubInit.c

ttkStubLib.o: $(TTK_DIR)/ttkStubLib.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkStubLib.c
	$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ $(TTK_DIR)/ttkStubLib.c

ttkTagSet.o: $(TTK_DIR)/ttkTagSet.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkTagSet.c

ttkTheme.o: $(TTK_DIR)/ttkTheme.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkTheme.c

1482
1483
1484
1485
1486
1487
1488





1489
1490
1491
1492
1493
1494
1495
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473







+
+
+
+
+








ttkWidget.o: $(TTK_DIR)/ttkWidget.c
	$(CC) -c $(CC_SWITCHES) $(TTK_DIR)/ttkWidget.c

ttkMacOSXTheme.o: $(MAC_OSX_DIR)/ttkMacOSXTheme.c
	$(CC) -c $(CC_SWITCHES) $(MAC_OSX_DIR)/ttkMacOSXTheme.c

tkUuid.h: $(TOP_DIR)/manifest.uuid
	echo "#define TK_VERSION_UUID \\" >$@
	cat $(TOP_DIR)/manifest.uuid >>$@
	echo "" >>$@

.c.o:
	$(CC) -c $(CC_SWITCHES) $<

#
# Target to regenerate header files and stub files from the *.decls tables.
#

1503
1504
1505
1506
1507
1508
1509
1510

1511
1512
1513
1514
1515
1516
1517
1481
1482
1483
1484
1485
1486
1487

1488
1489
1490
1491
1492
1493
1494
1495







-
+







	@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
	$(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
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







-
-
-
-
+








-
-
+
+

-
+

-
-
-
-
-
+
+
+
+
+
+
+




-
-
+
+






-
-
-
-
-
+
+
+
+
+



-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+



-
+

-
-
-
-
+
+
+


-
-
+
+


-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+


-
+


-
+


-
+


-
+












-
+


-
+


-
-
+
+

-
-
+
+


-
-
+
+
+
+







# 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)/configure: $(UNIX_DIR)/configure.in $(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
	printf "git-" >$(TOP_DIR)/manifest.uuid
	(cd $(TOP_DIR); git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid || printf "unknown" >$(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
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 \
	mkdir -p $(DISTDIR)/unix
	cp -p $(TOP_DIR)/manifest.uuid $(DISTDIR)
	cp -p $(UNIX_DIR)/*.c $(UNIX_DIR)/tkUnixDefault.h \
		$(UNIX_DIR)/tkUnixInt.h $(UNIX_DIR)/tkUnixPort.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
	$(DIST_INSTALL_SCRIPT) $(UNIX_DIR)/configure $(DISTDIR)/unix
	$(INSTALL_DATA_DIR) $(DISTDIR)/bitmaps
	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;)
	$(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 \
	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]
	$(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 \
	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 -p $(TOP_DIR)/win/configure \
		$(TOP_DIR)/win/*.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 \
		$(TOP_DIR)/win/*.c $(TOP_DIR)/win/*.bat \
		$(TOP_DIR)/win/tkWin.h $(TOP_DIR)/win/tkWinDefault.h \
		$(TOP_DIR)/win/tkWinInt.h \
		$(TOP_DIR)/win/tkWinPort.h $(TOP_DIR)/win/tkWinSendCom.h \
		$(TOP_DIR)/win/*.vc $(TOP_DIR)/win/README \
		$(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)/*.sdef $(MAC_OSX_DIR)/configure \
		$(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 \
	cp -p $(TOP_DIR)/license.terms $(DISTDIR)/macosx
	mkdir $(DISTDIR)/macosx/Tk.xcode
	cp -p $(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 \
	mkdir $(DISTDIR)/macosx/Tk.xcodeproj
	cp -p $(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 \
	mkdir $(DISTDIR)/compat
	cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/compat/unistd.h \
		$(TOP_DIR)/compat/stdlib.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
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/ttk
	$(DIST_INSTALL_DATA) $(TOP_DIR)/library/ttk/*.tcl $(DISTDIR)/library/ttk
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/images
	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 \
		$(DIST_INSTALL_DATA) $$i $(DISTDIR)/$$i; \
		cp $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/msgs
	mkdir $(DISTDIR)/library/msgs
	@(cd $(TOP_DIR); for i in library/msgs/*.msg ; do \
	    if [ -f $$i ] ; then \
		$(DIST_INSTALL_DATA) $$i $(DISTDIR)/$$i; \
		cp $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/demos
	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
	$(INSTALL_DATA_DIR) $(DISTDIR)/library/demos/images
	mkdir $(DISTDIR)/library/demos/images
	@(cd $(TOP_DIR); for i in library/demos/images/* ; do \
	    if [ -f $$i ] ; then \
		$(DIST_INSTALL_DATA) $$i $(DISTDIR)/$$i; \
		cp $$i $(DISTDIR)/$$i; \
	    fi; \
	done;)
	$(INSTALL_DATA_DIR) $(DISTDIR)/doc
	$(DIST_INSTALL_DATA) $(TOP_DIR)/license.terms $(TOP_DIR)/doc/*.[13n] \
	mkdir $(DISTDIR)/doc
	cp -p $(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} \
	mkdir $(DISTDIR)/tests
	cp -p $(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
	mkdir $(DISTDIR)/tests/ttk
	cp -p $(TEST_DIR)/ttk/*.{test,tcl} $(DISTDIR)/tests/ttk
	mkdir -p $(DISTDIR)/.github/workflows
	cp -p $(TOP_DIR)/.github/workflows/*.yml $(DISTDIR)/.github/workflows

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)

#
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
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#! /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.6])
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.6
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=6
TK_PATCH_LEVEL=".16"
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.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

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

#--------------------------------------------------------------------
# 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_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[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='$(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_COMPILE_IFELSE([AC_LANG_PROGRAM([[#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_COMPILE_IFELSE([AC_LANG_PROGRAM([[#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_LINK_IFELSE([AC_LANG_PROGRAM([[#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_LINK_IFELSE([AC_LANG_PROGRAM([[#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_LINK_IFELSE([AC_LANG_PROGRAM([[
		    #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_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		    #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 -framework QuartzCore"
    if test -d "/System/Library/Frameworks/UniformTypeIdentifiers.framework"; then
	LIBS="$LIBS -weak_framework UniformTypeIdentifiers"
    fi
    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_LINK_IFELSE([AC_LANG_PROGRAM([[
	#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

#--------------------------------------------------------------------
# Check whether XKeycodeToKeysym is deprecated in X11 headers.
#--------------------------------------------------------------------

if test $tk_aqua = no && test "$GCC" = yes; then
    AC_MSG_CHECKING([whether XKeycodeToKeysym is deprecated])
    tk_oldCFlags=$CFLAGS
    CFLAGS="$CFLAGS -Werror"
    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
	#include <X11/Xlib.h>
    ]], [[
	XKeycodeToKeysym(0,0,0);
    ]])],[
	AC_MSG_RESULT([no])
    ],[
    AC_MSG_RESULT([yes])
	AC_DEFINE(XKEYCODETOKEYSYM_IS_DEPRECATED, 1, [Is XKeycodeToKeysym deprecated?])
	])
    CFLAGS=$tk_oldCFlags
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_WISH_LIBS=${EXTRA_WISH_LIBS}' -sectcreate __TEXT __credits_html Credits.html'
    if test "${SHARED_BUILD}" = "0"; then
	EXTRA_WISH_LIBS=${EXTRA_WISH_LIBS}' -ObjC'
    fi
    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 Credits.html:../macosx/Credits.html.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 Credits.html to $(LIB_INSTALL_DIR)/Resources/" && $(INSTALL_DATA_DIR) "$(LIB_INSTALL_DIR)/Resources" && $(INSTALL_DATA) Credits.html "$(LIB_INSTALL_DIR)/Resources"'
    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"'
	EXTRA_INSTALL_BINARIES="$EXTRA_INSTALL_BINARIES"' && echo "Installing Credits.html to $(BIN_INSTALL_DIR)/../Resources" && $(INSTALL_DATA) Credits.html "$(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}\""

#------------------------------------------------------------------------
# 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
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
scriptversion=2020-11-14.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
#
69
70
71
72
73
74
75

76
77
78
79
80
81
82
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83







+







# 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

backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=

99
100
101
102
103
104
105
106

107
108
109
110

111
112

113
114
115
116
117
118








119
120
121
122
123
124
125
100
101
102
103
104
105
106

107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135







-
+




+

-
+






+
+
+
+
+
+
+
+







In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -C            install only if different (preserve 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.
  -p            pass -p to $cpprog.
  -s            $stripprog installed files.
  -S OPTION     $stripprog installed files using OPTION.
  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
  -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

By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.

If -S is not specified, no backups are attempted.

Email bug reports to bug-automake@gnu.org.
Automake home page: https://www.gnu.org/software/automake/
"

while test $# -ne 0; do
  case $1 in
    -c) ;;

    -C) copy_on_change=true;;
138
139
140
141
142
143
144


145
146
147

148
149
150
151
152
153
154
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
166







+
+


-
+







            exit 1;;
        esac
        shift;;

    -o) chowncmd="$chownprog $2"
        shift;;

    -p) cpprog="$cpprog -p";;

    -s) stripcmd=$stripprog;;

    -S) stripcmd="$stripprog $2"
    -S) backupsuffix="$2"
        shift;;

    -t)
        is_target_a_directory=always
        dst_arg=$2
        # Protect names problematic for 'test' and other utilities.
        case $dst_arg in
259
260
261
262
263
264
265




266
267
268
269
270
271
272
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288







+
+
+
+







  esac

  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
    # Don't chown directories that already exist.
    if test $dstdir_status = 0; then
      chowncmd=""
    fi
  else

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2
473
474
475
476
477
478
479







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496

497
498
499
500
501
502
503
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







+
+
+
+
+
+
+














-
+

-
+







       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
      # If $backupsuffix is set, and the file being installed
      # already exists, attempt a backup.  Don't worry if it fails,
      # e.g., if mv doesn't support -f.
      if test -n "$backupsuffix" && test -f "$dst"; then
        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
      fi

      # 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 $rmcmd "$dst" 2>/dev/null ||
          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
          } ||
          { echo "$0: cannot unlink or rename $dst" >&2
            (exit 1); exit 1
          }
        } &&

        # Now rename the file to the real destination.
Changes to unix/installManPage.
1
2
3
4
5
6
7

8

9
10
11
12
13
14
15


16
17
18
19
20
21
22
1
2
3
4
5
6
7
8

9
10
11
12
13
14


15
16
17
18
19
20
21
22
23







+
-
+





-
-
+
+







#!/bin/sh

########################################################################
### Parse Options
###

Gzip=:
Sym=""
SymOrLoc=""
Loc=""
Gz=""
Suffix=""

while true; do
    case $1 in
        -s | --symlinks  ) SymOrLoc="-s "      ;;
        -z | --compress  )     Gzip=$2;  shift ;;
	-s | --symlinks  )      Sym="-s "      ;;
	-z | --compress  )     Gzip=$2;  shift ;;
	-e | --extension )       Gz=$2;  shift ;;
	-x | --suffix    )   Suffix=$2;  shift ;;
	-*) cat <<EOF
Unknown option "$1". Supported options:
    -s         Use symbolic links for manpages with multiple names.
    -z PROG    Use PROG to compress manual pages.
    -e EXT     Defines the extension added by -z PROG when compressing.
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58







-
+







    echo "source manual page file must exist"
    exit 1
fi
if test -d "$Dir" ; then : ; else
    echo "target directory must exist"
    exit 1
fi
test -z "$SymOrLoc" && SymOrLoc="$Dir/"
test -z "$Sym" && Loc="$Dir/"

########################################################################
### Extract Target Names from Manual Page
###

# A sed script to parse the alternative names out of a man page.
#
113
114
115
116
117
118
119
120

121
122
123
124
125
114
115
116
117
118
119
120

121
122
123
124
125
126







-
+





    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"
	ln $Sym"$Loc$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
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],
	    AS_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig="${withval}")
	    [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 )
89
90
91
92
93
94
95
96

97
98
99
100


101
102
103
104
105
106
107
89
90
91
92
93
94
95

96
97
98


99
100
101
102
103
104
105
106
107







-
+


-
-
+
+







	    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/tcl8.6 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` \
			`ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
157
158
159
160
161
162
163
164

165
166

167
168
169
170
171
172
173
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],
	    AS_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig="${withval}")
	    [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 )
222
223
224
225
226
227
228
229

230
231
232
233


234
235
236
237
238
239
240
222
223
224
225
226
227
228

229
230
231


232
233
234
235
236
237
238
239
240







-
+


-
-
+
+







	    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/tk8.6 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` \
			`ls -d /usr/local/lib/tk8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
283
284
285
286
287
288
289
290

291
292
293

294
295
296
297
298
299
300
301
302
303
304
305



306
307
308
309
310
311
312
283
284
285
286
287
288
289

290
291
292

293
294
295
296
297
298
299
300
301
302



303
304
305
306
307
308
309
310
311
312







-
+


-
+









-
-
-
+
+
+







#		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
        AC_MSG_RESULT([loading])
	AC_MSG_RESULT([loading])
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
	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.
    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}"
	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}"
    elif test "`uname -s`" = "Darwin"; then
	# If Tcl was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tcl.framework installed in an arbitrary location.
	case ${TCL_DEFS} in
	    *TCL_FRAMEWORK*)
		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
356
357
358
359
360
361
362
363

364
365
366

367
368
369
370
371
372
373
374
375
376
377
378



379
380
381
382
383
384
385
356
357
358
359
360
361
362

363
364
365

366
367
368
369
370
371
372
373
374
375



376
377
378
379
380
381
382
383
384
385







-
+


-
+









-
-
-
+
+
+







#		TK_BIN_DIR
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TKCONFIG], [
    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])

    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
        AC_MSG_RESULT([loading])
	AC_MSG_RESULT([loading])
	. "${TK_BIN_DIR}/tkConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
	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.
    if test -f "${TK_BIN_DIR}/Makefile" ; then
        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
	TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
	TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
	TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
    elif test "`uname -s`" = "Darwin"; then
	# If Tk was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tk.framework installed in an arbitrary location.
	case ${TK_DEFS} in
	    *TK_FRAMEWORK*)
		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
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
504
505
506
507
508
509
510

511
512
513








514
515
516
517
518
519
520







-
+


-
-
-
-
-
-
-
-







#	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],
	AS_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?])
547
548
549
550
551
552
553
554

555
556
557
558
559
560
561
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553







-
+







#		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],
	    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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    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: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])

    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)
	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])
    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.
605
606
607
608
609
610
611
612

613
614
615
616
617
618
619
704
705
706
707
708
709
710

711
712
713
714
715
716
717
718







-
+







#		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],
	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.
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])
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
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







-
+










-
-
+
+







#
#	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],
	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_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
	    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
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







-
+

-
-
+
+




-
+






-
+













-
+






-
+










-
+
+








+




-
-
+
+






+
+
+
+
+
+







#			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],
	AS_HELP_STRING([--enable-man-symlinks],
	    [use symlinks for the manpages (default: off)]),
	test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks",
	enableval="no")
	[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],
	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")
	[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],
	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")
	[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.
#	"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 "${TEA_PLATFORM}" = "windows" ; then
	    tcl_cv_sys_version=windows
	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
846
847
848
849
850
851
852
853
854


855
856
857
858
859
860
861
953
954
955
956
957
958
959


960
961
962
963
964
965
966
967
968







-
-
+
+







#                       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
#                       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
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







-
+








-
+












-
+

+
-
-
+
+












-
+








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],
	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,
	AC_HELP_STRING([--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_TRY_LINK([
	AC_LINK_IFELSE([AC_LANG_PROGRAM([[
	    extern __attribute__((__visibility__("hidden"))) void f(void);
	    void f(void) {}]], [[f();]])],
	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
	    tcl_cv_cc_visibility_hidden=no)
	    [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],
	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.

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
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







-
+
-
-
-
-
-
-
-
-










-
+


-
+







    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"
	CFLAGS_WARNING="-Wall -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"])
    AS_IF([test "x${SHLIB_VERSION}" = x],[SHLIB_VERSION=".1.0"],[SHLIB_VERSION=".${SHLIB_VERSION}"])
    case $system in
	AIX-*)
	    AS_IF([test "$GCC" != "yes"], [
	    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
1119
1120
1121
1122
1123
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







-
+









-
-
-


-
+



-
-
-
+
+
+




+
+
+


-
+

-
+







	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*)
	CYGWIN_*|MINGW32_*|MSYS_*)
	    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([
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#ifdef __CYGWIN__
		    #error cygwin
		#endif
		], [],
		ac_cv_cygwin=no,
		ac_cv_cygwin=yes)
		]], [[]])],
		[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"
		echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args --enable-64bit --host=x86_64-w64-mingw32"
		# The eval makes quoting arguments work.
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix
		if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args --enable-64bit --host=x86_64-w64-mingw32; cd ../unix
		then :
		else
		    { echo "configure: error: configure failed for ../win" 1>&2; exit 1; }
		fi
	    fi
	    ;;
	dgux*)
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
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







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
+













+
+
+
+
+
+
+
+
+
+
+








+
-
+








-
+


















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

















-
+


+
-
-
-
-
+
+
+
+
+















+
-
-
-
-
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+

















-
-
+
+





-
+




-
-
+
+





+
+
+
+
+
+
+
+
+
+
+
+





-
+







+
-
+












+
-
-
+
+











-
+





-
+
















-
-
-
-
+
+
+
+



-
+












-
-
-
-
+
+
+
+






-
+




+
+
+
+
+
+
+
+
+
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+

-
+










+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+





+







	    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"
	        ])
		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)
	Linux*|GNU*|NetBSD-Debian|DragonFly-*|FreeBSD-*)
	    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"

	    case $system in
	    DragonFly-*|FreeBSD-*)
		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"])
	    ;;
	    esac

	    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([[]], [[]])],
		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
			    [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
	    # 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
	    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}'
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
	    LDFLAGS="-Wl,-export-dynamic"
	    CFLAGS_OPTIMIZE="-O2"
	    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"
		# 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"
		# 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
		;;
	    esac
	    ;;
	Darwin-*)
	    CFLAGS_OPTIMIZE="-Os"
	    CFLAGS_OPTIMIZE="-O2"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
	    # preprocessing tests and compiling tests, move any -isysroot and
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
	    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)
			    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)
		    i386|x86_64)
			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)
			    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
			]);;
		    arm64)
			AC_CACHE_CHECK([if compiler accepts -arch arm64 flag],
				tcl_cv_cc_arch_arm64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch arm64"
			    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
				    [tcl_cv_cc_arch_arm64=yes],[tcl_cv_cc_arch_arm64=no])
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_arm64 = yes], [
			    CFLAGS="$CFLAGS -arch arm64"
			    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) ' \
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \
		    && 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],
		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
		    [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_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],
		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
			tcl_cv_ld_search_paths_first=no)
			[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"
	    LD_LIBRARY_PATH_VAR="DYLD_FALLBACK_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],
		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_TRY_LINK([#include <CoreFoundation/CoreFoundation.h>],
			[CFBundleRef b = CFBundleGetMainBundle();],
			tcl_cv_lib_corefoundation=yes,
			tcl_cv_lib_corefoundation=no)
		    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])
			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)
			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"
			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='${CC} -shared'
	    ], [
	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
		SHLIB_LD='${CC} -non_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 -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"
		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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    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
1740
1919
1920
1921
1922
1923
1924
1925


1926
1927
1928
1929
1930
1931
1932
1933
1934







-
-
+
+







	    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])
		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=""
	    ;;
    esac
1752
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765
1766
1946
1947
1948
1949
1950
1951
1952

1953
1954
1955
1956
1957
1958
1959
1960







-
+







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],
	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
1871
1872
1873
1874
1875
1876

1877
1878
1879
1880
1881
1882
1883
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







-
-
+
+


-

-
+
















-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
+

-
-
-
-
-
-
+
+
+
+
+
+




-
+

-
+







-
+


-
-
-
+
+
+

-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+














+







    # 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*) ;;
	    CYGWIN_*|MINGW32_*|MSYS_*) ;;
	    HP-UX*) ;;
	    Darwin-*) ;;
	    IRIX*) ;;
	    Linux*|GNU*) ;;
	    NetBSD-*|OpenBSD-*) ;;
	    OSF1-V*) ;;
	    OSF1-*) ;;
	    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=${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)"'
	    DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
	], [
	    INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
	])
    ], [
        LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}
	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)"'
	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}'
    ], [
        MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS} ; ${RANLIB} [$]@'
	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}"])
	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.
    # 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([],
    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

		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
    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto"
    AC_CACHE_CHECK(for working -fno-lto,
	ac_cv_nolto,
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
	[ac_cv_nolto=yes],
	[ac_cv_nolto=no])
    )
    AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have <stdbool.h>?])],)
    CFLAGS=$hold_cflags
    if test "$ac_cv_nolto" = "yes" ; then
	CFLAGS_NOLTO="-fno-lto"
    else
	CFLAGS_NOLTO=""
    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)
    AC_SUBST(PLAT_SRCS)
    AC_SUBST(LDAIX_SRC)
    AC_SUBST(CFLAGS)
    AC_SUBST(CFLAGS_DEBUG)
    AC_SUBST(CFLAGS_OPTIMIZE)
    AC_SUBST(CFLAGS_WARNING)
    AC_SUBST(CFLAGS_NOLTO)

    AC_SUBST(LDFLAGS)
    AC_SUBST(LDFLAGS_DEBUG)
    AC_SUBST(LDFLAGS_OPTIMIZE)
    AC_SUBST(CC_SEARCH_FLAGS)
    AC_SUBST(LD_SEARCH_FLAGS)

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
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







-
-
+
+










+
+











-
-
+
+

















-
+





+
+



+


















-
+







])

#--------------------------------------------------------------------
# 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
#	    - 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_FLOAT_H
#		NO_VALUES_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>], [
    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)])
]])],[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(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_HAVE_HEADERS(sys/param.h)
    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
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







-
+









-
+







#--------------------------------------------------------------------

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")
	    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_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", 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"
2089
2090
2091
2092
2093
2094
2095




2096
2097
2098
2099
2100
2101
2102
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315







+
+
+
+







    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])
	    ;;
	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
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







-
-
+
+
+





-
-
+
+
+









-
-
+
+
+

-
-
+
+







-
-
+
+
+

-
-
+
+










-
-
+
+






-
-
-
-
-
-
-







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)])
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[struct tm tm; (void)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)])
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#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;
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>
#include <stdlib.h>]],
	[[extern long timezone;
	    timezone += 1;
	    exit (0);],
	    tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
	    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;
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>
#include <stdlib.h>]],
	    [[extern time_t timezone;
		timezone += 1;
		exit (0);],
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
		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.
#	Things like the math library (-lm), socket stuff (-lsocket vs.
#	-lnsl), zlib (-lz) and libtommath (-ltommath) 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
#
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-















-
-
+





+
-
+
-
-
-
-
+
+
+

-
+









-
-
+
+
-
-







    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.
#
# Arguments:
#	None
#
# Results:
#
#	Might define the following vars:
#		_ISOC99_SOURCE
#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64
#		_FILE_OFFSET_BITS
#
#--------------------------------------------------------------------

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]])],
	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
	    [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[
	    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)))
]$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])
	AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building])
	tcl_flags="$tcl_flags $1"
    fi
])

AC_DEFUN([SC_TCL_EARLY_FLAGS],[
    AC_MSG_CHECKING([for required early compiler flags])
    tcl_flags=""
    SC_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
	[char *p = (char *)strtoll; char *q = (char *)strtoull;])
    SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
	[struct stat64 buf; int i = stat64("/", &buf);])
    SC_TCL_EARLY_FLAG(_FILE_OFFSET_BITS,[#include <sys/stat.h>],
	[switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }],64)
    SC_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
	[char *p = (char *)open64;])
    if test "x${tcl_flags}" = "x" ; then
	AC_MSG_RESULT([none])
    else
	AC_MSG_RESULT([${tcl_flags}])
    fi
])

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
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







+








-
-
-
+
+
+


-
-
-
+
+
+

-
-
+
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
+
+
+





-
-
-
-
+
+
+
+





-
-
-
+
+
+







-
-
-
+
+
+



-
-
+
+







#
#	Might define the following vars:
#		TCL_WIDE_INT_IS_LONG
#		TCL_WIDE_INT_TYPE
#		HAVE_STRUCT_DIRENT64, HAVE_DIR64
#		HAVE_STRUCT_STAT64
#		HAVE_TYPE_OFF64_T
#		_TIME_BITS
#
#--------------------------------------------------------------------

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
	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_TRY_COMPILE(,[switch (0) {
            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
        }],tcl_cv_type_64bit=${tcl_type_64bit})])
	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, [Do 'long' and 'long long' have the same size (64-bit)?])
	AC_MSG_RESULT([yes])
	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 64-bit time_t], tcl_cv_time_t_64,[
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]],
		[[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
		[tcl_cv_time_t_64=yes],[tcl_cv_time_t_64=no])])
	if test "x${tcl_cv_time_t_64}" = "xno" ; then
	    # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64
	    # which SC_TCL_EARLY_FLAGS has defined if necessary.
	    AC_CACHE_CHECK([if _TIME_BITS=64 enables 64-bit time_t], tcl_cv__time_bits,[
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _TIME_BITS 64
#include <sys/types.h>]],
		    [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
		    [tcl_cv__time_bits=yes],[tcl_cv__time_bits=no])])
	    if test "x${tcl_cv__time_bits}" = "xyes" ; then
		AC_DEFINE(_TIME_BITS, 64, [_TIME_BITS=64 enables 64-bit time_t.])
	    fi
	fi

	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)])
	    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_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)])
	    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_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
],
		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
	    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_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
],
		tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
	    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
		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])
	else
	    AC_MSG_RESULT([no])
	fi
    fi
])
2440
2441
2442
2443
2444
2445
2446
2447

2448
2449

2450
2451
2452
2453
2454
2455
2456
2616
2617
2618
2619
2620
2621
2622

2623
2624

2625
2626
2627
2628
2629
2630
2631
2632







-
+

-
+







#	Will define the following vars:
#		TCL_CFGVAL_ENCODING
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_CFG_ENCODING], [
    AC_ARG_WITH(encoding,
	AC_HELP_STRING([--with-encoding],
	AS_HELP_STRING([--with-encoding],
	    [encoding for configuration values (default: iso8859-1)]),
	with_tcencoding=${withval})
	[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
2649
2650
2651
2652
2653
2654
2655

2656
2657
2658


2659
2660
2661
2662
2663
2664
2665
2666
2667







-
+


-
-
+
+







#
#--------------------------------------------------------------------

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([[
	    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))
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
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







-
+

-
+










-
+






-
+

-
+










-
+








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([
    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_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([
	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_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
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







-
+

-
+







-
+






-
+

-
+







-
+






-
+

-
+





-
+








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([
    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_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([
	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_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([
	    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_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
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
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







-
+


-
+






-
+






-
+


-
+






-
+







#		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([
    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_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([
	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_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
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







-
+


-
+






-
+






-
+


-
+






-
+







#		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([
    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_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([
	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_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
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







-
+


-
+






-
+






-
+


-
+






-
+







#		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([
    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_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([
	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_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
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







-
+


-
+






-
+






-
+


-
+






-
+







#		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([
    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_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([
	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_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
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
3090
3091
3092
3093
3094
3095
3096

3097
3098
3099
3100
3101



























































































































3102
3103
3104







-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



#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])
	[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:
Changes to unix/tk.pc.in.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13






-







# 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@
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
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
Version:       8.6.16
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
Buildrequires: XFree86-devel tcl >= %version
Requires:      tcl >= %version

%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.
12
13
14
15
16
17
18




19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39



40


41
42
43
44
45
46
47
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55







+
+
+
+





-
+















+
+
+
-
+
+







 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#undef BUILD_tk
#undef STATIC_BUILD
#include "tk.h"
#include "tkPort.h"
#if TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7
#   define Tcl_LibraryInitProc Tcl_PackageInitProc
#   define Tcl_StaticLibrary Tcl_StaticPackage
#endif

#ifdef TK_TEST
#ifdef __cplusplus
extern "C" {
#endif
extern Tcl_PackageInitProc Tktest_Init;
extern Tcl_LibraryInitProc 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
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#   define MODULE_SCOPE extern
#	define MODULE_SCOPE extern
#   endif
#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.,
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
84
85
86
87
88
89
90



91
92
93
94
95
96
97







-
-
-







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. */
}

/*
115
116
117
118
119
120
121
122

123
124
125
126
127

128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
120
121
122
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 ((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);
    Tcl_StaticLibrary(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);
	Tcl_SetExitProc(TkpExitProc);
    }
#endif

#ifdef TK_TEST
    if (Tktest_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tktest", Tktest_Init, 0);
    Tcl_StaticLibrary(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) {
Changes to unix/tkConfig.h.in.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6



7
8
9
10
11
12
13






-
-
-







/* ../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? */
24
25
26
27
28
29
30
31

32
33
34

35
36
37
38


39
40
41





42
43
44
45
46
47


48
49
50


51
52
53
54
55
56
57
21
22
23
24
25
26
27

28
29
30

31
32
33


34
35
36


37
38
39
40
41
42
43
44
45


46
47
48


49
50
51
52
53
54
55
56
57







-
+


-
+


-
-
+
+

-
-
+
+
+
+
+




-
-
+
+

-
-
+
+








/* 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). */
/* Define to 1 if you have the 'Xft' library (-lXft). */
#undef HAVE_LIBXFT

/* Define to 1 if you have the `lseek64' function. */
/* 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 `open64' function. */
#undef HAVE_OPEN64
/* Define to 1 if you have the 'pthread_atfork' function. */
#undef HAVE_PTHREAD_ATFORK

/* Define to 1 if you have the 'pthread_attr_setstacksize' function. */
#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE

/* 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 <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_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. */
#undef HAVE_STRINGS_H

86
87
88
89
90
91
92



93
94
95
96
97
98
99
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102







+
+
+







#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

107
108
109
110
111
112
113



114
115
116
117
118
119
120
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126







+
+
+







#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 <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

129
130
131
132
133
134
135
136



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159


160


161
162
163
164
165
166


167
168
169
170
171
172
173



174
175
176
177
178
179
180
181
182
183
184
185



186
187
188



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206






207
208
209
210
211
212
213
214


215
216
217
218
219

220
221
222

223
224
225
226
227
228
229
230
231

232
233
234

235
236
237

238
239
240

241
242
243
244
245
246
247
248
249
250
251



252
135
136
137
138
139
140
141

142
143
144
145
146



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210






211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237

238
239
240

241
242
243
244
245
246
247
248
249

250
251
252

253
254
255

256
257
258

259
260
261
262
263
264
265
266
267
268


269
270
271
272







-
+
+
+


-
-
-


















+
+
-
+
+





-
+
+







+
+
+












+
+
+



+
+
+




-
-
-
-
-
-








+
+
+
+
+
+







-
+
+




-
+


-
+








-
+


-
+


-
+


-
+









-
-
+
+
+


/* 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. */
/* Define to 1 if all of the C89 standard headers exist (not just the ones
   required in a freestanding environment). This macro is provided for
   backward compatibility; new code need not use it. */
#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

/* Are we building with threads enabled? */
#undef TCL_THREADS
/* Do 'long' and 'long long' have the same size (64-bit)? */

/* 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>. */
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. This
   macro is obsolete. */
#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 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

/* Is XKeycodeToKeysym deprecated? */
#undef XKEYCODETOKEYSYM_IS_DEPRECATED

/* Are Darwin SUSv3 extensions available? */
#undef _DARWIN_C_SOURCE

/* Add the _FILE_OFFSET_BITS flag when building */
#undef _FILE_OFFSET_BITS

/* Add the _ISOC99_SOURCE flag when building */
#undef _ISOC99_SOURCE

/* Add the _LARGEFILE64_SOURCE flag when building */
#undef _LARGEFILE64_SOURCE

/* Add the _LARGEFILE_SOURCE64 flag when building */
#undef _LARGEFILE_SOURCE64

/* # needed in sys/socket.h Should OS/390 do the right thing with sockets? */
#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

/* _TIME_BITS=64 enables 64-bit time_t. */
#undef _TIME_BITS

/* 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.  */
/* Define to 1 if type 'char' is unsigned and your compiler does not
   predefine this macro.  */
#ifndef __CHAR_UNSIGNED__
# undef __CHAR_UNSIGNED__
#endif

/* Define to `int' if <sys/types.h> doesn't define. */
/* Define as 'int' if <sys/types.h> doesn't define. */
#undef gid_t

/* Define to `__inline__' or `__inline' if that's what the C compiler
/* 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. */
/* Define to 'int' if <sys/types.h> does not define. */
#undef mode_t

/* Define to `int' if <sys/types.h> does not define. */
/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* Define as 'unsigned int' if <stddef.h> doesn't define. */
#undef size_t

/* Define to `int' if <sys/types.h> doesn't define. */
/* Define as '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
    /* override */ #undef PACKAGE_TARNAME
    /* override */ #undef PACKAGE_VERSION
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */
Changes to unix/tkConfig.sh.in.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
19
20
21
22
23
24
25

26
27
28
29
30
31
32







-








# -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@'

91
92
93
94
95
96
97
98
99
100
90
91
92
93
94
95
96










-
-
-
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@'
Changes to unix/tkUnix.c.
104
105
106
107
108
109
110
111
112


113
114
115
116
117
118
119






























120
121
122
123
124
125
126
104
105
106
107
108
109
110


111
112







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149







-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







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;
  /*
   * This function intentionally left blank
  (void)y;
  (void)state;

  /*
   * This function intentionally left blank
   */
}
   */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCopyRegion --
 *
 *	Makes the destination region a copy of the source region.
 *	Currently unused on X11.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

extern int XUnionRegion(Region srca, Region srcb, Region dr_return);

void
TkpCopyRegion(
    TkRegion dst,
    TkRegion src)
{
    /* XUnionRegion() in Xlib is optimized to detect copying */
    XUnionRegion((Region)src, (Region)src, (Region)dst);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpBuildRegionFromAlphaData --
 *
 *	Set up a rectangle of the given region based on the supplied alpha
200
201
202
203
204
205
206

207

208



209
210
211
212
213
214
215
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239
240
241
242







+
-
+

+
+
+







 * Side effects:
 *	None.
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
 #ifdef HAVE_XSS
    Display *dpy)		/* The display for which to query the inactive
   Display *dpy)		/* The display for which to query the inactive
				 * time. */
#else
  TCL_UNUSED(Display *))
#endif /* HAVE_XSS */
{
    long inactiveTime = -1;
#ifdef HAVE_XSS
    int eventBase, errorBase, major, minor;

    /*
     * Calling XScreenSaverQueryVersion seems to be needed to prevent a crash
Changes to unix/tkUnix3d.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16



17
18
19
20
21
22
23
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25






-
+








-
+
+
+







/*
 * tkUnix3d.c --
 *
 *	This file contains the platform specific routines for drawing 3d
 *	borders in the Motif style.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * 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.
 */

#include "tkInt.h"
#include "tk3d.h"

#if !(defined(_WIN32) || defined(MAC_OSX_TK))
#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * This structure is used to keep track of the extra colors used by Unix 3D
 * borders.
 */
Changes to unix/tkUnixButton.c.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







/*
 * tkUnixButton.c --
 *
 *	This file implements the Unix specific portion of the button widgets.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkButton.h"
Changes to unix/tkUnixColor.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkUnixColor.c --
 *
 *	This file contains the platform specific color routines needed for X
 *	support.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * 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.
 */

#include "tkUnixInt.h"
#include "tkColor.h"
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
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 = ckalloc(sizeof(TkColor));
    tkColPtr->color = color;

    return tkColPtr;
}

/*
 *----------------------------------------------------------------------
216
217
218
219
220
221
222
223

224
225
226
227
228
229
230
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));
    TkColor *tkColPtr = 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
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280

281
282

283
284
285

286
287
288
289
290
291
292

293
294
295
296
297
298
299
300







-
+








-
+

-
+


-
+






-
+







{
    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;
    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 = ckalloc(sizeof(TkStressedCmap));
	    stressPtr->colormap = colormap;
	    templ.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));
	    template.visualid = XVisualIDFromVisual(Tk_Visual(tkwin));

	    visInfoPtr = XGetVisualInfo(Tk_Display(tkwin),
		    VisualIDMask, &templ, &numFound);
		    VisualIDMask, &template, &numFound);
	    if (numFound < 1) {
		Tcl_Panic("FindClosestColor couldn't lookup visual");
	    }

	    stressPtr->numColors = visInfoPtr->colormap_size;
	    XFree((char *) visInfoPtr);
	    stressPtr->colorPtr = (XColor *)
	    stressPtr->colorPtr =
		    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);
Changes to unix/tkUnixConfig.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
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40




41
42
43
44
45
46
47
48
49
50






-
+

















-
+















-
-
-
-










/*
 * tkUnixConfig.c --
 *
 *	This module implements the Unix system defaults for the configuration
 *	package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright (c) 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"


/*
 *----------------------------------------------------------------------
 *
 * TkpGetSystemDefault --
 *
 *	Given a dbName and className for a configuration option, return a
 *	string representation of the option.
 *
 * Results:
 *	Returns a Tk_Uid that is the string identifier that identifies this
 *	Returns a Tcl_Obj* with the string identifier that identifies this
 *	option. Returns NULL if there are no system defaults that match this
 *	pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
 */

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
 * fill-column: 78
 * End:
 */
Changes to unix/tkUnixCursor.c.
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348







-
+







	}

	cursor = CreateCursorFromTableOrFile(interp, tkwin, argc, argv,
		tkCursorPtr);
    }

    if (cursor != None) {
	cursorPtr = (TkUnixCursor *)ckalloc(sizeof(TkUnixCursor));
	cursorPtr = ckalloc(sizeof(TkUnixCursor));
	cursorPtr->info.cursor = (Tk_Cursor) cursor;
	cursorPtr->display = display;
    }

  cleanup:
    if (argv != NULL) {
	ckfree(argv);
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
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 = ckalloc(sizeof(TkUnixCursor));
	cursorPtr->info.cursor = (Tk_Cursor) cursor;
	cursorPtr->display = display;
    }
    return (TkCursor *) cursorPtr;
}

/*
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
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42







-











-







 * 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
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88

89
90
91
92
93
94
95
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
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_BORDER_WIDTH		"1"
#define DEF_BUTTON_CURSOR		""
#define DEF_BUTTON_COMPOUND		"none"
#define DEF_BUTTON_COMMAND		""
#define DEF_BUTTON_DEFAULT		"disabled"
#define DEF_BUTTON_DISABLED_FG_COLOR	DISABLED
#define DEF_BUTTON_DISABLED_FG_MONO	""
#define DEF_LABEL_FG			BLACK
#define DEF_BUTTON_FG			BLACK
#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		BLACK
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
#define DEF_BUTTON_IMAGE		NULL
#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		INDICATOR
#define DEF_BUTTON_SELECT_MONO		BLACK
#define DEF_BUTTON_SELECT_IMAGE		NULL
#define DEF_BUTTON_SELECT_IMAGE		((char *) NULL)
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#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
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		NULL
#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
149
150
151
152
153
154
155


156
157
158
159
160
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_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_SHOW			((char *) NULL)
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		NULL
#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_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
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251




252
253
254

255
256
257


258
259

260
261
262


263
264
265

266
267
268


269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297


298
299
300
301
302
303
304
229
230
231
232
233
234
235

236
237
238
239
240
241
242




243
244
245
246
247
248

249
250


251
252
253

254
255


256
257
258
259

260
261


262
263
264

265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289


290
291
292
293
294
295
296
297
298







-
+






-
-
-
-
+
+
+
+


-
+

-
-
+
+

-
+

-
-
+
+


-
+

-
-
+
+

-
+











-













-
-
+
+







#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_TAKE_FOCUS		((char *) 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_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		NULL
#define DEF_MENU_ENTRY_COMMAND		((char *) NULL)
#define DEF_MENU_ENTRY_COMPOUND 	"none"
#define DEF_MENU_ENTRY_FG		NULL
#define DEF_MENU_ENTRY_FONT		NULL
#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		NULL
#define DEF_MENU_ENTRY_IMAGE		((char *) NULL)
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		NULL
#define DEF_MENU_ENTRY_MENU		NULL
#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	NULL
#define DEF_MENU_ENTRY_SELECT_IMAGE	((char *) NULL)
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#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		NULL
#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_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_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
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326







-
+







#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_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"
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436







-
+







#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_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
449
450
451
452
453
454
455

456
457
458
459
460
461
462
463







-
+







#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_TAKE_FOCUS	((char *) NULL)
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"11"

/*
 * Defaults for texts:
 */
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
482
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







-
+














-
+







#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_INACTIVE_SELECT_BG_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_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	""

/*
Deleted unix/tkUnixDialog.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

































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
 * tkUnixDialog.c --
 *
 *	Contains the Unix implementation of the common dialog boxes:
 *
 * 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.
 */

#include "tkUnixInt.h"

/*
 * The wrapper code for Unix is actually set up in library/tk.tcl these days;
 * the procedure names used here are probably wrong too...
 */

#ifdef TK_OBSOLETE_UNIX_DIALOG_WRAPPERS

/*
 *----------------------------------------------------------------------
 *
 * EvalObjv --
 *
 *	Invokes the Tcl procedure with the arguments.
 *
 * Results:
 *	Returns the result of the evaluation of the command.
 *
 * Side effects:
 *	The command may be autoloaded.
 *
 *----------------------------------------------------------------------
 */

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;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_ChooseColorObjCmd --
 *
 *	This procedure implements the color dialog box for the Unix platform.
 *	See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	A dialog window is created the first time this procedure is called.
 *	This window is not destroyed and will be reused the next time the
 *	application invokes the "tk_chooseColor" command.
 *
 *----------------------------------------------------------------------
 */

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);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOpenFileCmd --
 *
 *	This procedure implements the "open file" dialog box for the Unix
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	A dialog window is created the first this procedure is called. This
 *	window is not destroyed and will be reused the next time the
 *	application invokes the "tk_getOpenFile" or "tk_getSaveFile" command.
 *
 *----------------------------------------------------------------------
 */

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);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetSaveFileCmd --
 *
 *	Same as Tk_GetOpenFileCmd but opens a "save file" dialog box instead.
 *
 * Results:
 *	Same as Tk_GetOpenFileCmd.
 *
 * Side effects:
 *	Same as Tk_GetOpenFileCmd.
 *
 *----------------------------------------------------------------------
 */

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);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxCmd --
 *
 *	This procedure implements the MessageBox window for the Unix
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	None. The MessageBox window will be destroy before this procedure
 *	returns.
 *
 *----------------------------------------------------------------------
 */

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.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







 * 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. */
    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:
 */

57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71







-
+







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. */
    TkRegion 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);
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100







-
+







    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)) {
    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
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
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);
	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, info->region,
		info->region);
	XUnionRectWithRegion(&rect, (Region) info->region,
		(Region) info->region);
	rect.x += info->dx;
	rect.y += info->dy;
	XUnionRectWithRegion(&rect, info->region,
		info->region);
	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
198
199
200
201
202
203
204


205
206
207
208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226

227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243







-
-






-
+













-
+

-





-
+











TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    (void)bgGC;

    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --
 * TkpDrawFrame --
 *
 *	This function draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrameEx(
TkpDrawFrame(
    Tk_Window tkwin,
    Drawable drawable,
    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    Tk_Fill3DRectangle(tkwin, drawable, border, highlightWidth,
    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.
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116







-
+







    TkWindow *winPtr = (TkWindow *) tkwin;
    TkWindow *usePtr;
    int anyError;
    Window parent;
    Tk_ErrorHandler handler;
    Container *containerPtr;
    XWindowAttributes parentAtts;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            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;
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188







-
+







	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 = ckalloc(sizeof(Container));
	containerPtr->parent = parent;
	containerPtr->parentRoot = parentAtts.root;
	containerPtr->parentPtr = NULL;
	containerPtr->wrapper = None;
	containerPtr->nextPtr = tsdPtr->firstContainerPtr;
	tsdPtr->firstContainerPtr = containerPtr;
    }
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226







-
+







TkpMakeWindow(
    TkWindow *winPtr,		/* Tk's information about the window that is
				 * to be instantiated. */
    Window parent)		/* Window system token for the parent in which
				 * the window is to be created. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->flags & TK_EMBEDDED) {
	/*
	 * This window is embedded. Don't create the new window in the given
	 * parent; instead, create it as a child of the root window of the
	 * container's screen. The window will get reparented into a wrapper
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
291







-
+








-
+







void
TkpMakeContainer(
    Tk_Window tkwin)		/* Token for a window that is about to become
				 * a container. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * 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 = 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;
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
328
329
330
331
332
333
334

335

336
337
338
339
340
341
342







-
+
-








static int
EmbedErrorProc(
    ClientData clientData,	/* Points to integer to set. */
    XErrorEvent *errEventPtr)	/* Points to information about error (not
				 * used). */
{
    int *iPtr = (int *)clientData;
    int *iPtr = clientData;
    (void)errEventPtr;

    *iPtr = 1;
    return 0;
}

/*
 *----------------------------------------------------------------------
359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372







-
+







 */

static void
EmbeddedEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *winPtr = 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
390
391
392
393
394
395
396

397
398
399

400
401
402
403
404
405
406
407







-
+


-
+







 */

static void
ContainerEventProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *winPtr = clientData;
    Container *containerPtr;
    Tk_ErrorHandler errHandler;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            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).
     */
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511

512
513
514
515
516
517
518
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;
    Container *containerPtr = clientData;
    Tk_ErrorHandler errHandler;

    if (eventPtr->type == ConfigureNotify) {
        /*
         * Send a ConfigureNotify  to the embedded application.
         */

        if (containerPtr->embeddedPtr != NULL) {
        if (containerPtr->embeddedPtr != None) {
            TkDoConfigureNotify(containerPtr->embeddedPtr);
        }
	if (containerPtr->wrapper != None) {

	    /*
	     * Ignore errors, since the embedded application could have
	     * deleted its window.
551
552
553
554
555
556
557
558

559
560
561
562
563
564
565
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564







-
+







 */

static void
EmbedFocusProc(
    ClientData clientData,	/* Token for container window. */
    XEvent *eventPtr)		/* ResizeRequest event. */
{
    Container *containerPtr = (Container *)clientData;
    Container *containerPtr = 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
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
708
709
710
711
712
713
714

715
716
717
718
719
720
721
722







-
+








TkWindow *
TkpGetOtherWindow(
    TkWindow *winPtr)		/* Tk's structure for a container or embedded
				 * window. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr;
            containerPtr != NULL;
	    containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parentPtr;
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
754
755
756
757
758
759
760

761
762
763
764
765
766
767
768







-
+







    TkWindow *winPtr,		/* Window to which the event was originally
				 * reported. */
    XEvent *eventPtr)		/* X event to redirect (should be KeyPress or
				 * KeyRelease). */
{
    Container *containerPtr;
    Window saved;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * First, find the top-level window corresponding to winPtr.
     */

    while (1) {
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
826
827
828
829
830
831
832

833
834
835
836
837
838
839
840







-
+







				 * window; should be embedded. */
    int force)			/* One means that the container should claim
				 * the focus if it doesn't currently have
				 * it. */
{
    XEvent event;
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (!(topLevelPtr->flags & TK_EMBEDDED)) {
	return;
    }

    for (containerPtr = tsdPtr->firstContainerPtr;
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
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







-
+









-
+

-







 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkpTestembedCmd(
    ClientData dummy,	/* Main window for application. */
    ClientData clientData,	/* 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 *)
    ThreadSpecificData *tsdPtr =
            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);
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
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







-
+
















-
+







	    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);
	    snprintf(buffer, sizeof(buffer), "0x%lx", 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);
	    snprintf(buffer, sizeof(buffer), "0x%lx", containerPtr->wrapper);
	    Tcl_DStringAppendElement(&dString, buffer);
	} else {
	    Tcl_DStringAppendElement(&dString, "XXX");
	}
	/* Embedded window pathName */
	if (containerPtr->embeddedPtr == NULL ||
	    embeddedInterp != interp) {
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
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







-
+











+








static void
EmbedWindowDeleted(
    TkWindow *winPtr)		/* Tk's information about window that was
				 * deleted. */
{
    Container *containerPtr, *prevPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Find the Container structure for this window work. Delete the
     * information about the embedded application and free the container's
     * record.
     */

    prevPtr = NULL;
    containerPtr = tsdPtr->firstContainerPtr;
    while (1) {
	if (containerPtr == NULL) return;
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->wrapper = None;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    containerPtr->parentPtr = NULL;
1023
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036







-
+







 */

Window
TkUnixContainerId(
    TkWindow *winPtr)		/* Tk's structure for an embedded window. */
{
    Container *containerPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (containerPtr = tsdPtr->firstContainerPtr;
            containerPtr != NULL; containerPtr = containerPtr->nextPtr) {
	if (containerPtr->embeddedPtr == winPtr) {
	    return containerPtr->parent;
	}
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1175
1176
1177
1178
1179
1180
1181

1182
1183
1184
1185
1186
1187
1188







-







    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
Changes to unix/tkUnixEvent.c.
8
9
10
11
12
13
14
15

16
17
18




19
20
21
22
23
24
25
8
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 "tkUnixInt.h"
#include <signal.h>
#undef register /* Keyword "register" is used in XKBlib.h, so don't try tricky things here */
#ifdef HAVE_XKBKEYCODETOKEYSYM
#define XkbOpenDisplay XkbOpenDisplay_ /* Move out of the way, conflicting definitions */
#include <X11/XKBlib.h>
#undef XkbOpenDisplay
#  include <X11/XKBlib.h>
#else
#  define XkbOpenDisplay(D,V,E,M,m,R) (((void)D),((void)V),((void)E),((void)M),((void)m),((void)R),(NULL))
#endif

/*
 * The following static indicates whether this module has been initialized in
 * the current thread.
 */

typedef struct {
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
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. */
    ClientData clientData)	/* Not used. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)dummy;

    Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
    tsdPtr->initialized = 0;
}

/*
 *----------------------------------------------------------------------
125
126
127
128
129
130
131

132
133

134
135
136
137
138
139
140
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141







+

-
+







    TkDisplay *dispPtr;
    Display *display;
    int event = 0;
    int error = 0;
    int major = 1;
    int minor = 0;
    int reason = 0;
    unsigned int use_xkb = 0;
    /* Disabled, until we have a better test. See [Bug 3613668] */
#if 0
#if 0 && defined(XKEYCODETOKEYSYM_IS_DEPRECATED) && defined(TCL_THREADS)
    static int xinited = 0;
    static Tcl_Mutex xinitMutex = NULL;

    if (!xinited) {
	Tcl_MutexLock(&xinitMutex);
	if (!xinited) {
	    /* Necessary for threaded apps, of no consequence otherwise  */
149
150
151
152
153
154
155
156

157
158


159
160

161









162
163
164
165
166

167
168

169

170
171
172
173
174
175
176
150
151
152
153
154
155
156

157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190







-
+


+
+

-
+

+
+
+
+
+
+
+
+
+




-
+


+

+







	}
	Tcl_MutexUnlock(&xinitMutex);
    }
#endif

    /*
    ** Bug [3607830]: Before using Xkb, it must be initialized and confirmed
    **                that the server supports it.  The XkbOpenDisplay call
    **                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(displayNameStr, &event, &error, &major,
    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));
    dispPtr = ckalloc(sizeof(TkDisplay));
    memset(dispPtr, 0, sizeof(TkDisplay));
    dispPtr->display = display;
    dispPtr->flags |= use_xkb;
#ifdef TK_USE_INPUT_METHODS
    XSetLocaleModifiers("");
    OpenIM(dispPtr);
    XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
#endif
    Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
	    DisplayFileProc, dispPtr);

294
295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311
312
313
308
309
310
311
312
313
314

315
316
317
318
319

320
321
322
323
324
325
326







-
+




-







 *	Tcl even if there is no more data on the X connection.
 *
 *----------------------------------------------------------------------
 */

static void
DisplaySetupProc(
    ClientData dummy,	/* Not used. */
    ClientData clientData,	/* 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) {
361
362
363
364
365
366
367
368



369
370
371
372
373
374
375
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390







-
+
+
+







     * 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) {
	if ((event.type >= VirtualEvent) && (event.type <= MouseWheelEvent)) {
	    /* See [fe87e9af39]. Those are internal Tk event types, if they come
	     * from an external source they most likely would be totally mis-interpreted */
	    continue;
	}
	w = None;
	if (event.type == KeyPress || event.type == KeyRelease) {
	    for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
		if (dispPtr == NULL) {
		    break;
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
442
443
444
445
446
447
448

449
450
451
452

453
454
455
456
457
458
459







-
+



-







 *	Moves queued events onto the Tcl event queue.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayCheckProc(
    ClientData dummy,	/* Not used. */
    ClientData clientData,	/* Not used. */
    int flags)
{
    TkDisplay *dispPtr;
    (void)dummy;

    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
480
481
482
483
484
485
486

487
488
489

490
491
492
493
494
495
496







-
+


-







 */

static void
DisplayFileProc(
    ClientData clientData,	/* The display pointer. */
    int flags)			/* Should be TCL_READABLE. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    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
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
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







-
-














-
-







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);
}
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
740
741
742
743
744
745
746




747
748
749
750
751
752
753







-
-
-
-







OpenIM(
    TkDisplay *dispPtr)		/* Tk's structure for the display. */
{
    int i;
    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 */
Changes to unix/tkUnixFont.c.
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115







-
+







				/* Builtin space for a limited number of
				 * SubFonts. */
    int numSubFonts;		/* Length of following array. */
    SubFont *subFontArray;	/* Array of SubFonts that have been loaded in
				 * 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
				 * InitFont() from the original set of font
				 * attributes. Usually points to
				 * staticSubFonts, but may point to malloced
				 * space if there are lots of SubFonts. */
    SubFont controlSubFont;	/* Font to use to display control-character
				 * expansions. */

    Display *display;		/* Display that owns font. */
242
243
244
245
246
247
248



























249
250
251
252
253
254
255
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







			    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);

/*
 *-------------------------------------------------------------------------
 *
 * XLoadQueryFontNoXError --
 *
 *	This function is XLoadQueryFont wrapped in a NULL error handler.
 *	It is a temporary workaround for ticket [36e379c01b],
 *	"macOS Ventura, X11 build with XQuartz: crash in XLoadQueryFont",
 *	which actually is issue #216 in XQuartz:
 *	https://github.com/XQuartz/XQuartz/issues/216
 *
 *-------------------------------------------------------------------------
 */

static XFontStruct *
XLoadQueryFontNoXError(Display *display, char *name)
{
    XFontStruct *fontStructPtr = NULL;
    Tk_ErrorHandler handler;

    /* 45 is the major opcode of X_OpenFont */
    handler = Tk_CreateErrorHandler(display, BadValue, 45, -1, NULL, NULL);
    fontStructPtr = XLoadQueryFont(display, name);
    Tk_DeleteErrorHandler(handler);
    return fontStructPtr;
}

/*
 *-------------------------------------------------------------------------
 *
 * FontPkgCleanup --
 *
 *	This function is called when an application is created. It initializes
386
387
388
389
390
391
392
393

394
395
396
397
398
399
400
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427







-
+







    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 hexChars[] = "0123456789abcdef";
    static const char mapChars[] = {
	0, 0, 0, 0, 0, 0, 0,
	'a', 'b', 't', 'n', 'v', 'f', 'r'
    };

    result = TCL_OK;

425
426
427
428
429
430
431
432
433
434
435




436
437
438
439
440
441
442
452
453
454
455
456
457
458




459
460
461
462
463
464
465
466
467
468
469







-
-
-
-
+
+
+
+







	    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[2] = 'f';
	    dst[3] = 'f';
	    dst[4] = 'f';
	    dst[5] = 'd';
	    dst += 6;
	}
    }
    *srcReadPtr = src - srcStart;
    *dstWrotePtr = dst - dstStart;
    *dstCharsPtr = dst - dstStart;
    return result;
549
550
551
552
553
554
555








556
557
558
559
560
561
562
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597







+
+
+
+
+
+
+
+







 *	Returns TCL_OK if conversion was successful.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

#if defined(USE_TCL_STUBS)
/* Since the UCS-2BE encoding is only used when Tk is dynamically loaded in Tcl 8.6,
 * make sure that Tcl_UtfCharComplete is ALWAYS the pre-TIP #575 version,
 * even though Tk is being compiled with -DTCL_NO_DEPRECATED! */
#   undef Tcl_UtfCharComplete
#   define Tcl_UtfCharComplete ((int (*)(const char *, int))(void *)((&tclStubsPtr->tcl_PkgProvideEx)[326]))
#endif

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. */
688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
723
724
725
726
727
728
729

730
731
732
733
734
735
736
737







-
+







	    hasWild = 1;
	}
    }
    if ((dashes < 14) && !hasWild && hasSpace) {
	return NULL;
    }

    fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), name);
    fontStructPtr = XLoadQueryFontNoXError(Tk_Display(tkwin), (char *)name);
    if (fontStructPtr == NULL) {
	/*
	 * Handle all names that look like XLFDs here. Otherwise, when
	 * TkpGetFontFromAttributes is called from generic code, any foundry
	 * or encoding information specified in the XLFD will have been parsed
	 * out and lost. But make sure we don't have an "-option value" string
	 * since TkFontParseXLFD would return a false success when attempting
943
944
945
946
947
948
949
950

951
952
953
954
955
956
957
978
979
980
981
982
983
984

985
986
987
988
989
990
991
992







-
+







 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    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
1007
1008
1009
1010
1011
1012
1013

1014

1015
1016
1017
1018
1019
1020
1021
1042
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
1057







+
-
+







				 * 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 curByte;
    int curX, curByte, ch;
    int curX, 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.
     */
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
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







-
+










-
-







    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. */
    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. */
    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);
}

/*
 *-------------------------------------------------------------------------
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
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







+
+
+
+







-
-
-
-







    const char *const *const *fontFallbacks;
    SubFont *subFontPtr;
    Tcl_DString ds;

    if (ch < 0 || ch >= FONTMAP_NUMCHARS) {
	ch = 0xFFFD;
    }

    if (FontMapLookup(&fontPtr->controlSubFont, ch)) {
	return &fontPtr->controlSubFont;
    }

    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;
    }

    /*
     * Keep track of all face names that we check, so we don't check some name
     * multiple times if it can be reached by multiple paths.
     */

    Tcl_DStringInit(&ds);

2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115




2116
2117
2118
2119
2120
2121
2122
2139
2140
2141
2142
2143
2144
2145




2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156







-
-
-
-
+
+
+
+







    /*
     * 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,
	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;
	    }
	}
    }
2759
2760
2761
2762
2763
2764
2765
2766

2767
2768

2769
2770
2771
2772
2773
2774
2775
2793
2794
2795
2796
2797
2798
2799

2800
2801

2802
2803
2804
2805
2806
2807
2808
2809







-
+

-
+








static XFontStruct *
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
    int bestIdx[],		/* Indices into above array for XLFD of best
				 * bitmapped and best scalable font. */
    unsigned bestScore[2])	/* Scores of best bitmapped and best scalable
    unsigned bestScore[])	/* 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;
2798
2799
2800
2801
2802
2803
2804
2805

2806
2807
2808

2809
2810
2811
2812

2813
2814
2815
2816
2817
2818
2819
2832
2833
2834
2835
2836
2837
2838

2839
2840
2841

2842
2843
2844
2845

2846
2847
2848
2849
2850
2851
2852
2853







-
+


-
+



-
+







	    str = strchr(str + 1, '-');
	}
	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]],
	snprintf(buf, sizeof(buf), "%.200s-%d-*-*-*-*-*%s", nameList[bestIdx[1]],
		(int)(-wantPtr->fa.size+0.5), rest);
	*str = '-';
	fontStructPtr = XLoadQueryFont(display, buf);
	fontStructPtr = XLoadQueryFontNoXError(display, buf);
	bestScore[1] = INT_MAX;
    }
    if (fontStructPtr == NULL) {
	fontStructPtr = XLoadQueryFont(display, nameList[bestIdx[0]]);
	fontStructPtr = XLoadQueryFontNoXError(display, nameList[bestIdx[0]]);
	if (fontStructPtr == NULL) {
	    /*
	     * This shouldn't happen because the font name is one of the names
	     * that X gave us to use, but it does anyhow.
	     */

	    if (bestScore[1] < INT_MAX) {
2845
2846
2847
2848
2849
2850
2851
2852

2853
2854

2855
2856
2857
2858
2859
2860
2861
2879
2880
2881
2882
2883
2884
2885

2886
2887

2888
2889
2890
2891
2892
2893
2894
2895







-
+

-
+








static XFontStruct *
GetSystemFont(
    Display *display)		/* Display for new XFontStruct. */
{
    XFontStruct *fontStructPtr;

    fontStructPtr = XLoadQueryFont(display, "fixed");
    fontStructPtr = XLoadQueryFontNoXError(display, "fixed");
    if (fontStructPtr == NULL) {
	fontStructPtr = XLoadQueryFont(display, "*");
	fontStructPtr = XLoadQueryFontNoXError(display, "*");
	if (fontStructPtr == NULL) {
	    Tcl_Panic("TkpGetFontFromAttributes: cannot get any font");
	}
    }
    return fontStructPtr;
}

2936
2937
2938
2939
2940
2941
2942
2943

2944
2945
2946
2947
2948
2949
2950
2970
2971
2972
2973
2974
2975
2976

2977
2978
2979
2980
2981
2982
2983
2984







-
+







    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);
    snprintf(buf, sizeof(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. */
Changes to unix/tkUnixInit.c.
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146

147
148
149

150




151

152
153
154
155
156
157
158
159
160







-




+







-
+


-

-
-
-
-

-

+







 *
 * Side effects:
 *	Same as for Tcl_MacOSXOpenVersionedBundleResources.
 *
 *----------------------------------------------------------------------
 */

#ifdef TK_FRAMEWORK
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_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
	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
Changes to unix/tkUnixKey.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
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20




21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43






-
+







+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/*
 * tkUnixKey.c --
 *
 *	This file contains routines for dealing with international keyboard
 *	input.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright (c) 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef __GNUC__
/*
 * We know that XKeycodeToKeysym is deprecated, nothing we can do about it.
 */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#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

/*
** 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:
 */

/*
 *----------------------------------------------------------------------
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128







-
+








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;
    int len;
    Tcl_DString buf;
    TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

    /*
     * If we have the value cached already, use it now. [Bug 1373712]
     */

156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188







-
+







	 * 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);
		&kePtr->keysym, &status);

	/*
	 * If the buffer wasn't big enough, grow the buffer and try again.
	 */

	if (status == XBufferOverflow) {
	    Tcl_DStringSetLength(&buf, len);
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253







-
+







    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
 * 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,
291
292
293
294
295
296
297




298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341







+
+
+
+














-
+







 * Side effects:
 *	In the first call for a given display, keycode-to-KeySym maps get
 *	loaded.
 *
 *----------------------------------------------------------------------
 */

#ifdef __GNUC__
#   pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif

KeySym
TkpGetKeySym(
    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;
	return NoSymbol;
    }

    /*
     * Refresh the mapping information if it's stale. This must happen before
     * we do any input method processing. [Bug 3599312]
     */

355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421







-
+


















-
+










-
+







	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,
    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.
     */

#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,
	    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 = XkbKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode,
	sym = TkKeycodeToKeysym(dispPtr, eventPtr->xkey.keycode,
		0, index & ~1);
    }
    return sym;
}

/*
 *--------------------------------------------------------------
417
418
419
420
421
422
423
424


425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472







-
+
+

















-
+







TkpInitKeymapInfo(
    TkDisplay *dispPtr)		/* Display for which to recompute keymap
				 * information. */
{
    XModifierKeymap *modMapPtr;
    KeyCode *codePtr;
    KeySym keysym;
    int count, i, j, max, arraySize;
    int count, i, max;
    int j, arraySize;
#define KEYCODE_ARRAY_SIZE 20

    dispPtr->bindInfoStale = 0;
    modMapPtr = XGetModifierMapping(dispPtr->display);

    /*
     * Check the keycodes associated with the Lock modifier. If any of them is
     * associated with the XK_Shift_Lock modifier, then Lock has to be
     * interpreted as Shift Lock, not Caps Lock.
     */

    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);
	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;
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498







-
+







    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);
	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);
	}
Changes to unix/tkUnixMenu.c.
1
2
3
4
5
6

7
8
9
10
11

12
13
14
15
16
17
18
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.
 * Copyright (c) 1996-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.
 */

#include "default.h"
#include "tkUnixInt.h"
#include "tkMenu.h"

/*
 * Constants used for menu drawing.
 */

438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
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);
	    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,
627
628
629
630
631
632
633

634
635
636
637
638
639
640
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642







+







    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;
856
857
858
859
860
861
862
863

864
865
866
867
868
869
870
858
859
860
861
862
863
864

865
866
867
868
869
870
871
872







-
+








	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);
	    start = TkUtfAtIndex(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;
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
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







-
+







-
-
-
-
-
-
-















+
+
+
+
+
+
+
+
+
+
+
+







 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter of the menu */
    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 menu y position so that the specified entry will be located
     * at the given coordinates.
     */

    if (index >= menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

    /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 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
1122
1123
1124
1125
1126
1127
1128
1129

1130
1131
1132
1133
1134
1135
1136
1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142
1143







-
+







	 * 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++) {
	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 {
1199
1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210
1211
1212
1213
1206
1207
1208
1209
1210
1211
1212

1213
1214
1215
1216
1217
1218
1219
1220







-
+







	    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++) {
	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;
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373



1374
1375

1376
1377

1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
1371
1372
1373
1374
1375
1376
1377



1378
1379
1380
1381

1382
1383

1384
1385
1386

1387
1388
1389
1390
1391
1392
1393
1394







-
-
-
+
+
+

-
+

-
+


-
+







	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;
		&& (cascadeEntryPtr->menuPtr->masterMenuPtr->tkwin != NULL)
		&& (menuPtr->masterMenuPtr->tkwin != NULL)) {
	    TkMenu *masterMenuPtr = cascadeEntryPtr->menuPtr->masterMenuPtr;
	    char *helpMenuName = (char *)ckalloc(strlen(Tk_PathName(
		    mainMenuPtr->tkwin)) + strlen(".help") + 1);
		    masterMenuPtr->tkwin)) + strlen(".help") + 1);

	    strcpy(helpMenuName, Tk_PathName(mainMenuPtr->tkwin));
	    strcpy(helpMenuName, Tk_PathName(masterMenuPtr->tkwin));
	    strcat(helpMenuName, ".help");
	    if (strcmp(helpMenuName,
		    Tk_PathName(menuPtr->mainMenuPtr->tkwin)) == 0) {
		    Tk_PathName(menuPtr->masterMenuPtr->tkwin)) == 0) {
		cascadeEntryPtr->entryFlags |= ENTRY_HELP_MENU;
	    } else {
		cascadeEntryPtr->entryFlags &= ~ENTRY_HELP_MENU;
	    }
	    ckfree(helpMenuName);
	}
    }
1701
1702
1703
1704
1705
1706
1707
1708

1709
1710
1711
1712
1713
1714
1715
1708
1709
1710
1711
1712
1713
1714

1715
1716
1717
1718
1719
1720
1721
1722







-
+







     * 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++) {
    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);
1796
1797
1798
1799
1800
1801
1802
1803

1804
1805
1806
1807
1808
1809
1810
1803
1804
1805
1806
1807
1808
1809

1810
1811
1812
1813
1814
1815
1816
1817







-
+







	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < (int)menuPtr->numEntries; j++) {
    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;
    }
1843
1844
1845
1846
1847
1848
1849
1850

1851
1852
1853
1854
1855
1856
1857
1850
1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1864







-
+







 *	An idle handler is set up to do the reconfiguration.
 *
 *----------------------------------------------------------------------
 */

void
TkpMenuNotifyToplevelCreate(
    TCL_UNUSED(Tcl_Interp *),	/* The interp the menu lives in. */
    TCL_UNUSED(Tcl_Interp *),		/* The interp the menu lives in. */
    TCL_UNUSED(const char *))	/* The name of the menu to reconfigure. */
{
    /*
     * Nothing to do.
     */
}

Changes to unix/tkUnixMenubu.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkUnixMenubu.c --
 *
 *	This file implements the Unix specific portion of the menubutton
 *	widget.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenubutton.h"
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
315
316
317
318
319
320
321

322
323
324
325
326
327
328







-







 *----------------------------------------------------------------------
 */

void
TkpDestroyMenuButton(
    TkMenuButton *mbPtr)
{
    (void)mbPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeMenuButtonGeometry --
 *
Changes to unix/tkUnixPort.h.
22
23
24
25
26
27
28



29


30
31
32
33
34
35
36
37
38
39

40
41
42
43

44
45
46
47
48
49

50
51

52




53
54
55
56
57
58
59
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42

43
44
45
46

47
48
49
50
51
52

53
54
55
56

57
58
59
60
61
62
63
64
65
66
67







+
+
+
-
+
+









-
+



-
+





-
+


+
-
+
+
+
+







#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#ifdef NO_STDLIB_H
#   include "../compat/stdlib.h"
#else
#include <stdlib.h>
#   include <stdlib.h>
#endif
#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
#ifdef TIME_WITH_SYS_TIME
#   include <sys/time.h>
#   include <time.h>
#else
#   if HAVE_SYS_TIME_H
#   ifdef HAVE_SYS_TIME_H
#	include <sys/time.h>
#   else
#	include <time.h>
#   endif
#endif
#if HAVE_INTTYPES_H
#ifdef HAVE_INTTYPES_H
#    include <inttypes.h>
#endif
#ifndef NO_UNISTD_H
#include <unistd.h>
#   include <unistd.h>
#else
#   include "../compat/unistd.h"
#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>
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121

























122
123
124
125
126
127
128
110
111
112
113
114
115
116
117













118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149







+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 * 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 *
#   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
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
181
182
187
188
189
190
191
192
193

194
195
196






197







-
+


-
-
-
-
-
-

/*
 * This macro stores a representation of the window handle in a string.
 * This should perhaps use the real size of an XID.
 */

#ifndef __CYGWIN__
#define TkpPrintWindowId(buf,w) \
	sprintf((buf), "%#08lx", (unsigned long) (w))
	snprintf((buf), TCL_INTEGER_SPACE, "0x%08lx", (unsigned long) (w))
#endif

/*
 * Used by tkWindow.c
 */

#define TkpHandleMapOrUnmap(tkwin, event)  Tk_HandleEvent(event)

#endif /* _UNIXPORT */
Changes to unix/tkUnixRFont.c.
8
9
10
11
12
13
14
15
16
17
18










19
20
21
22
23
24
25
8
9
10
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 "tkUnixInt.h"
#include "tkFont.h"
#include <X11/Xft/Xft.h>
#include <ctype.h>

#define MAX_CACHED_COLORS 16

/*
 * Debugging support...
 */

#define DEBUG_FONTSEL 0
#define DEBUG(arguments) \
    if (DEBUG_FONTSEL) { \
	printf arguments; fflush(stdout); \
    }

typedef struct {
    XftFont *ftFont;
    XftFont *ft0Font;
    FcPattern *source;
    FcCharSet *charset;
    double angle;
} UnixFtFace;
50
51
52
53
54
55
56




57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89




90


91
92
93
94
95
96
97
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114







+
+
+
+




















-












+
+
+
+
-
+
+







 * the information isn't retrievable from the GC.
 */

typedef struct {
    Region clipRegion;		/* The clipping region, or None. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

TCL_DECLARE_MUTEX(xftMutex);
#define LOCK Tcl_MutexLock(&xftMutex)
#define UNLOCK Tcl_MutexUnlock(&xftMutex)

/*
 *-------------------------------------------------------------------------
 *
 * 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. */
{
    static const Tcl_Config cfg[] = {
	{ "fontsystem", "xft" },
	{ 0,0 }
    };
    (void)mainPtr;

    Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, "utf-8");
}

static XftFont *
GetFont(
    UnixFtFont *fontPtr,
    FcChar32 ucs4,
    double angle)
128
129
130
131
132
133
134

135

136
137
138
139
140
141
142
143

144
145
146
147
148

149
150
151
152
153
154
155
156
157
158
159
160
161
162

163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185

186

187
188
189
190
191
192


193
194
195


196
197
198


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213


214
215
216




217

218
219
220
221
222
223
224
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211

212
213
214


215
216
217


218
219
220


221
222
223
224
225
226
227
228
229
230
231
232
233
234



235
236

237
238
239
240
241
242

243
244
245
246
247
248
249
250







+

+








+





+














+

+

















+





+
-
+
-



-
-
+
+

-
-
+
+

-
-
+
+












-
-
-
+
+
-


+
+
+
+
-
+








	mat.xx = mat.yy = c;
	mat.xy = -(mat.yx = s);

	if (angle != 0.0) {
	    FcPatternAddMatrix(pat, FC_MATRIX, &mat);
	}
	LOCK;
	ftFont = XftFontOpenPattern(fontPtr->display, pat);
	UNLOCK;
	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:
	     */

	    LOCK;
	    ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
		    FC_FAMILY, FcTypeString, "sans",
		    FC_SIZE, FcTypeDouble, 12.0,
		    FC_MATRIX, FcTypeMatrix, &mat,
		    NULL);
	    UNLOCK;
	}
	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) {
		LOCK;
		XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
		UNLOCK;
	    }
	    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(
    Tk_Window tkwin,
    XftFont *ftFont,
    TkFontAttributes *faPtr)
{
    const char *family = "Unknown";
    const char *const *familyPtr = &family;
    double ptSize, dblPxSize, size;
    int weight, slant, pxsize;
    int intPxSize, weight, slant;
    double size, ptsize;

    (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr);
    if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = ptsize;
	    &ptSize) == XftResultMatch) {
	size = ptSize;
    } else if (XftPatternGetDouble(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &ptsize) == XftResultMatch) {
	size = -ptsize;
	    &dblPxSize) == XftResultMatch) {
	size = -dblPxSize;
    } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0,
	    &pxsize) == XftResultMatch) {
	size = (double)-pxsize;
	    &intPxSize) == XftResultMatch) {
	size = (double)-intPxSize;
    } 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);
    DEBUG(("GetTkFontAttributes: family %s size %ld weight %d slant %d\n",
	    family, lround(size), weight, slant));
#endif /* DEBUG_FONTSEL */

    faPtr->family = Tk_GetUid(family);
    /*
     * Make sure that faPtr->size will be > 0 even
     * in the very unprobable case that size < 0
     */
    faPtr->size = size;
    faPtr->size = TkFontGetPoints(tkwin, 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;
}

/*
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302







-
+








static void
FinishedWithFont(
    UnixFtFont *fontPtr);

static int
InitFontErrorProc(
    ClientData clientData,
    void *clientData,
    TCL_UNUSED(XErrorEvent *))
{
    int *errorFlagPtr = (int *)clientData;

    if (errorFlagPtr != NULL) {
	*errorFlagPtr = 1;
    }
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386







-
+








-
+








    /*
     * Fill in platform-specific fields of TkFont.
     */

    errorFlag = 0;
    handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
		    -1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
		    -1, -1, -1, InitFontErrorProc, (void *)&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);
    GetTkFontAttributes(tkwin, ftFont, &fontPtr->font.fa);
    GetTkFontMetrics(ftFont, &fontPtr->font.fm);
    Tk_DeleteErrorHandler(handler);
    if (errorFlag) {
	FinishedWithFont(fontPtr);
	ckfree(fontPtr);
	return NULL;
    }
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
405
406
407
408
409
410
411

412
413
414
415
416
417
418
419







-
+







     */

    {
	TkFont *fPtr = &fontPtr->font;

	fPtr->underlinePos = fPtr->fm.descent / 2;
	handler = Tk_CreateErrorHandler(Tk_Display(tkwin),
			-1, -1, -1, InitFontErrorProc, (ClientData) &errorFlag);
			-1, -1, -1, InitFontErrorProc, (void *)&errorFlag);
	errorFlag = 0;
	Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
	Tk_DeleteErrorHandler(handler);
	if (errorFlag) {
	    FinishedWithFont(fontPtr);
	    ckfree(fontPtr);
	    return NULL;
415
416
417
418
419
420
421

422

423
424

425

426
427
428
429
430
431
432
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462







+

+


+

+







    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) {
	    LOCK;
	    XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
	    UNLOCK;
	}
	if (fontPtr->faces[i].ft0Font) {
	    LOCK;
	    XftFontClose(fontPtr->display, fontPtr->faces[i].ft0Font);
	    UNLOCK;
	}
	if (fontPtr->faces[i].charset) {
	    FcCharSetDestroy(fontPtr->faces[i].charset);
	}
    }
    if (fontPtr->faces) {
	ckfree(fontPtr->faces);
449
450
451
452
453
454
455
456
457


458
459
460
461
462
463
464
465
479
480
481
482
483
484
485


486
487

488
489
490
491
492
493
494







-
-
+
+
-







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);

    DEBUG(("TkpGetNativeFont: %s\n", name));
#endif /* DEBUG_FONTSEL */

    pattern = XftXlfdParse(name, FcFalse, FcFalse);
    if (!pattern) {
	return NULL;
    }

    /*
487
488
489
490
491
492
493
494
495
496
497



498
499
500
501
502
503
504
516
517
518
519
520
521
522




523
524
525
526
527
528
529
530
531
532







-
-
-
-
+
+
+







    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 */
    DEBUG(("TkpGetFontFromAttributes: %s %ld %d %d\n", faPtr->family,
	    lround(faPtr->size), faPtr->weight, faPtr->slant));

    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) {
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
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







-
+











-
+







 *	character.
 *
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    TCL_UNUSED(Tk_Window),	/* Window on the font's display */
    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 */
{
    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);
    GetTkFontAttributes(tkwin, 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. */
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
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







+
-
+


-
+




















-
-
+














-
+





+

-
+
+
+







    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XftFont *ftFont;
    FcChar32 c;
    XGlyphInfo extents;
    int clen;
    int clen, curX, newX, curByte, newByte, sawNonSpace;
    int curX, newX, curByte, newByte, sawNonSpace;
    int termByte = 0, termX = 0, errorFlag = 0;
    Tk_ErrorHandler handler;
#ifdef DEBUG_FONTSEL
#if 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;
	    return curByte;
	    goto measureCharsEnd;
	}

	source += clen;
	numBytes -= clen;
	if (c < 256 && isspace(c)) {		/* I18N: ??? */
	    if (sawNonSpace) {
		termByte = curByte;
		termX = curX;
		sawNonSpace = 0;
	    }
	} else {
	    sawNonSpace = 1;
	}

#ifdef DEBUG_FONTSEL
#if DEBUG_FONTSEL
	string[len++] = (char) c;
#endif /* DEBUG_FONTSEL */
	ftFont = GetFont(fontPtr, c, 0.0);

	if (!errorFlag) {
	    LOCK;
	    XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
	} else {
	    UNLOCK;
	}
	if (errorFlag) {
	    extents.xOff = 0;
	    errorFlag = 0;
	}

	newX = curX + extents.xOff;
	newByte = curByte + clen;
	if (maxLength >= 0 && newX > maxLength) {
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
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







+

-
+

-
+









-
+






-
-







	    }
	    break;
	}

	curX = newX;
	curByte = newByte;
    }
measureCharsEnd:
    Tk_DeleteErrorHandler(handler);
#ifdef DEBUG_FONTSEL
#if DEBUG_FONTSEL
    string[len] = '\0';
    printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
    DEBUG(("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,
    TCL_UNUSED(int),
    int rangeStart,
    int rangeLength,
    int maxLength,
    int flags,
    int *lengthPtr)
{
    (void) numBytes; /*unused*/

    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
	    maxLength, flags, lengthPtr);
}

/*
 *----------------------------------------------------------------------
 *
928
929
930
931
932
933
934
935

936
937
938
939

940
941
942
943
944
945
946
947
958
959
960
961
962
963
964

965
966
967


968

969
970
971
972
973
974
975







-
+


-
-
+
-







    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));
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (fontPtr->ftDraw == 0) {
#ifdef DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
	DEBUG(("Switch to drawable 0x%lx\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);

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
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







+


+












+


+








+

+







	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    LOCK;
	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);
	    UNLOCK;

	    /*
	     * 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) {
		    LOCK;
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    UNLOCK;
		    nspec = 0;
		}
	    }
	    x += metrics.xOff;
	    y += metrics.yOff;
	}
    }
    if (nspec) {
	LOCK;
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
	UNLOCK;
    }

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }
    if (fontPtr->font.fa.underline != 0) {
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
1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1105
1106


1107

1108
1109
1110
1111
1112
1113
1114







-
+








-
-
+
-







    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));
	    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);
	DEBUG(("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);

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
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







+


+
+
















-
-
-
-
+
+
+
+


+


+









+


+








+


+



-
+
+





-
-
+
-







		/*
		 * 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!
		 */

		LOCK;
		XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
			nglyph, &metrics);
		UNLOCK;

		/*
		 * 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)
		     * 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)
		     */

		    LOCK;
		    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
			    originX, originY, glyphs, nglyph);
		    UNLOCK;
		}
	    }
	    originX = ROUND16(x);
	    originY = ROUND16(y);
	    currentFtFont = ftFont;
	}
	glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
    }
    if (nglyph) {
	LOCK;
	XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
		nglyph, &metrics);
	UNLOCK;

	/*
	 * Draw glyph only when it fits entirely into 16 bit coords.
	 */

	if (x >= minCoord && y >= minCoord &&
	    x <= maxCoord - metrics.width &&
	    y <= maxCoord - metrics.height) {
	    LOCK;
	    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
		    originX, originY, glyphs, nglyph);
	    UNLOCK;
	}
    }
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
    int clen, nspec;
    int clen;
    int 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);
	DEBUG(("Switch to drawable 0x%lx\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);

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
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







+


+












+


+








+

+







	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);
	    LOCK;
	    XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
		    &metrics);
	    UNLOCK;

	    /*
	     * 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) {
		    LOCK;
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    UNLOCK;
		    nspec = 0;
		}
	    }
	    x += metrics.xOff*cosA + metrics.yOff*sinA;
	    y += metrics.yOff*cosA - metrics.xOff*sinA;
	}
    }
    if (nspec) {
	LOCK;
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
	UNLOCK;
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != NULL) {
	XftDrawSetClip(fontPtr->ftDraw, NULL);
    }
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
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







-
+








-
-



















-
+










-
-







-
+


-
+

-
+








    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. */
    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;

    (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. */
    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. */
    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. */
    TkRegion clipRegion)	/* The clipping region to install. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->clipRegion = clipRegion;
    tsdPtr->clipRegion = (Region)clipRegion;
}

/*
 * Local Variables:
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to unix/tkUnixScale.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
1
2
3

4
5


6
7
8
9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24



-
+

-
-
+
+








-
-
+
+







/*
 * tkUnixScale.c --
 *
 *	This file implements the X specific portion of the scrollbar widget.
 *	This file implements the X specific portion of the scale widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 * 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.
 */

#include "tkInt.h"
#include "tkScale.h"

#if defined(_WIN32)
#define snprintf _snprintf
#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Forward declarations for functions defined later in this file:
 */

static void		DisplayHorizontalScale(TkScale *scalePtr,
Changes to unix/tkUnixScrlbr.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkUnixScrollbar.c --
 *
 *	This file implements the Unix specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * 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.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
Changes to unix/tkUnixSelect.c.
1507
1508
1509
1510
1511
1512
1513
1514

1515
1516
1517
1518
1519
1520
1521
1507
1508
1509
1510
1511
1512
1513

1514
1515
1516
1517
1518
1519
1520
1521







-
+







    for ( ; numValues > 0; propPtr++, numValues--) {
	if (type == XA_ATOM) {
	    Tcl_DStringAppendElement(dsPtr,
		    Tk_GetAtomName(tkwin, (Atom) *propPtr));
	} else {
	    char buf[12];

	    sprintf(buf, "0x%x", (unsigned int) *propPtr);
	    snprintf(buf, sizeof(buf), "0x%x", (unsigned int) *propPtr);
	    Tcl_DStringAppendElement(dsPtr, buf);
	}
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

static void
1533
1534
1535
1536
1537
1538
1539
1540

1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1533
1534
1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552







-
+












     * hexadecimal string. We build the list in a Tcl_DString because this is
     * easier than trying to get the quoting correct ourselves.
     */

    for ( ; numValues > 0; propPtr++, numValues--) {
	char buf[12];

	sprintf(buf, "0x%x", (unsigned char) *propPtr);
	snprintf(buf, sizeof(buf), "0x%x", (unsigned char) *propPtr);
	Tcl_DStringAppendElement(dsPtr, buf);
    }
    Tcl_DStringAppend(dsPtr, " ", 1);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to unix/tkUnixSend.c.
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16








-
+







/*
 * tkUnixSend.c --
 *
 *	This file provides functions that implement the "send" command,
 *	allowing commands to be passed from interpreter to interpreter.
 *
 * Copyright (c) 1989-1994 The Regents of the University of California.
 * Copyright (c) 1994-1996 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * 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 "tkUnixInt.h"

472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486







-
+







				 * registered. */
    Window commWindow)		/* X identifier for comm. window of
				 * application. */
{
    char id[30], *newProp;
    int idLength, newBytes;

    sprintf(id, "%x ", (unsigned) commWindow);
    snprintf(id, sizeof(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);
871
872
873
874
875
876
877
878

879
880
881
882
883
884
885
871
872
873
874
875
876
877

878
879
880
881
882
883
884
885







-
+







		Tcl_DStringInit(&dString);
		Tcl_DStringAppend(&dString, name, -1);
		Tcl_DStringAppend(&dString, " #", 2);
		offset = Tcl_DStringLength(&dString);
		Tcl_DStringSetLength(&dString, offset+TCL_INTEGER_SPACE);
		actualName = Tcl_DStringValue(&dString);
	    }
	    sprintf(Tcl_DStringValue(&dString) + offset, "%d", i);
	    snprintf(Tcl_DStringValue(&dString) + offset, TCL_INTEGER_SPACE, "%d", i);
	}
	w = RegFindName(regPtr, actualName);
	if (w == None) {
	    break;
	}

	/*
978
979
980
981
982
983
984
985

986
987
988
989
990
991
992
978
979
980
981
982
983
984

985
986
987
988
989
990
991
992







-
+








    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,
	if (Tcl_GetIndexFromObjStruct(NULL, 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]),
1092
1093
1094
1095
1096
1097
1098
1099

1100
1101
1102
1103
1104
1105
1106
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105
1106







-
+







    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",
	snprintf(buffer, sizeof(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);
1616
1617
1618
1619
1620
1621
1622
1623

1624
1625
1626
1627
1628
1629
1630
1616
1617
1618
1619
1620
1621
1622

1623
1624
1625
1626
1627
1628
1629
1630







-
+







	     */

	returnResult:
	    if (commWindow != None) {
		if (result != TCL_OK) {
		    char buffer[TCL_INTEGER_SPACE];

		    sprintf(buffer, "%d", result);
		    snprintf(buffer, sizeof(buffer), "%d", result);
		    Tcl_DStringAppend(&reply, "\0-c ", 4);
		    Tcl_DStringAppend(&reply, buffer, -1);
		}
		(void) AppendPropCarefully(dispPtr->display, commWindow,
			dispPtr->commProperty, Tcl_DStringValue(&reply),
			Tcl_DStringLength(&reply) + 1, NULL);
		XFlush(dispPtr->display);
1792
1793
1794
1795
1796
1797
1798
1799

1800
1801
1802
1803
1804
1805
1806
1792
1793
1794
1795
1796
1797
1798

1799
1800
1801
1802
1803
1804
1805
1806







-
+







     * 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\"",
	    snprintf(pcPtr->result, strlen(pcPtr->target) + 50, "no application named \"%s\"",
		    pcPtr->target);
	    pcPtr->code = TCL_ERROR;
	    pcPtr->gotResponse = 1;
	    break;
	}
    }
    return 0;
2045
2046
2047
2048
2049
2050
2051
2052

2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2045
2046
2047
2048
2049
2050
2051

2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063







-
+











	    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));
	Tcl_SetObjResult(interp, Tcl_NewIntObj(localData.sendSerial+1));
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to unix/tkUnixWm.c.
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46







-
+







				 * 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)
    ((unsigned)((Tk_Offset(ProtocolHandler, command) + 1) + cmdLength))

/*
 * Data for [wm attributes] command:
 */

typedef struct {
    double alpha;		/* Transparency; 0.0=transparent, 1.0=opaque */
308
309
310
311
312
313
314
315

316
317
318
319
320

321
322
323
324
325
326
327
308
309
310
311
312
313
314

315
316
317
318
319

320
321
322
323
324
325
326
327







-
+




-
+







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 */
    NULL,			/* lostSlaveProc */
};
static const Tk_GeomMgr menubarMgrType = {
    "menubar",			/* name */
    MenubarReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
    NULL,			/* lostSlaveProc */
};

/*
 * Structures of the following type are used for communication between
 * WaitForEvent, WaitRestrictProc, and WaitTimeoutProc.
 */

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
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







-
+











-
-
-
+
+
+







-
-
+
+







	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 index, length;
    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)) {
    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_SetObjResult(interp, Tcl_NewWideIntObj(
		    (dispPtr->flags & TK_DISPLAY_WM_TRACING) != 0));
	    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;
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205




1206
1207
1208
1209
1210
1211
1212
1195
1196
1197
1198
1199
1200
1201




1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212







-
-
-
-
+
+
+
+







		"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);
	    results[0] = Tcl_NewIntObj(wmPtr->minAspect.x);
	    results[1] = Tcl_NewIntObj(wmPtr->minAspect.y);
	    results[2] = Tcl_NewIntObj(wmPtr->maxAspect.x);
	    results[3] = Tcl_NewIntObj(wmPtr->maxAspect.y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
1340
1341
1342
1343
1344
1345
1346
1347

1348
1349

1350
1351

1352
1353
1354
1355
1356
1357
1358
1340
1341
1342
1343
1344
1345
1346

1347
1348

1349
1350

1351
1352
1353
1354
1355
1356
1357
1358







-
+

-
+

-
+







{
    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);
	return Tcl_NewBooleanObj(wmPtr->attributes.topmost);
    case WMATT_ZOOMED:
	return Tcl_NewWideIntObj(wmPtr->attributes.zoomed != 0);
	return Tcl_NewBooleanObj(wmPtr->attributes.zoomed);
    case WMATT_FULLSCREEN:
	return Tcl_NewWideIntObj(wmPtr->attributes.fullscreen != 0);
	return Tcl_NewBooleanObj(wmPtr->attributes.fullscreen);
    case WMATT_TYPE:
	return GetNetWmType(winPtr);
    case _WMATT_LAST_ATTRIBUTE:
	break;
    }
    return NULL;
}
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
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







-
+








-
+









-
+







    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));
		    WmGetAttribute(winPtr, 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));
	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_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) {
	    if (WmSetAttribute(winPtr,interp,attribute,objv[i+1]) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	return TCL_OK;
    }

    Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");
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
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







+












-
+















-
+







    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 != 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]);
    argv3 = Tcl_GetStringFromObj(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, 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);
    wmPtr->clientMachine = (char *)ckalloc(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,
1874
1875
1876
1877
1878
1879
1880
1881

1882
1883
1884
1885
1886
1887
1888
1875
1876
1877
1878
1879
1880
1881

1882
1883
1884
1885
1886
1887
1888
1889







-
+







	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);
    snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)window);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
-
-
-
+
+
+
+










-
+







		"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);
	    results[0] = Tcl_NewIntObj(wmPtr->reqGridWidth);
	    results[1] = Tcl_NewIntObj(wmPtr->reqGridHeight);
	    results[2] = Tcl_NewIntObj(wmPtr->widthInc);
	    results[3] = Tcl_NewIntObj(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.
	 */

	wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
	wmPtr->sizeHintsFlags &= ~PBaseSize;
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
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
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







+











-
+







    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    Tk_Window tkwin2;
    WmInfo *wmPtr2;
    const 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_GetString(objv[3]);
    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
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117
2118
2119
2120
2121
2122







-
+







	    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);
	wmPtr->leaderName = (char *)ckalloc(length + 1);
	strcpy(wmPtr->leaderName, argv3);
    }
    UpdateHints(winPtr);
    return TCL_OK;
}

/*
2221
2222
2223
2224
2225
2226
2227
2228

2229
2230
2231
2232
2233
2234
2235

2236
2237
2238
2239
2240
2241
2242
2223
2224
2225
2226
2227
2228
2229

2230
2231
2232
2233
2234
2235
2236

2237
2238
2239
2240
2241
2242
2243
2244







-
+






-
+







		"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\"",
		"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",
		"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));
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
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







+














-
-
+
+







    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;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree(wmPtr->iconName);
	}
	argv3 = Tcl_GetString(objv[3]);
	wmPtr->iconName = (char *)ckalloc(objv[3]->length + 1);
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->iconName = ckalloc(length + 1);
	strcpy(wmPtr->iconName, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    UpdateTitle(winPtr);
	}
    }
    return TCL_OK;
}
2538
2539
2540
2541
2542
2543
2544
2545
2546


2547
2548
2549
2550
2551
2552
2553
2541
2542
2543
2544
2545
2546
2547


2548
2549
2550
2551
2552
2553
2554
2555
2556







-
-
+
+







	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);
	    results[0] = Tcl_NewIntObj(wmPtr->hints.icon_x);
	    results[1] = Tcl_NewIntObj(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 {
2595
2596
2597
2598
2599
2600
2601
2602

2603
2604
2605
2606
2607
2608
2609
2598
2599
2600
2601
2602
2603
2604

2605
2606
2607
2608
2609
2610
2611
2612







-
+








    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));
	    Tcl_SetObjResult(interp, TkNewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*
2777
2778
2779
2780
2781
2782
2783
2784
2785


2786
2787
2788
2789
2790
2791
2792
2780
2781
2782
2783
2784
2785
2786


2787
2788
2789
2790
2791
2792
2793
2794
2795







-
-
+
+







	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);
	results[0] = Tcl_NewIntObj(width);
	results[1] = Tcl_NewIntObj(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;
    }
2835
2836
2837
2838
2839
2840
2841
2842
2843


2844
2845
2846
2847
2848
2849
2850
2838
2839
2840
2841
2842
2843
2844


2845
2846
2847
2848
2849
2850
2851
2852
2853







-
-
+
+







    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);
	results[0] = Tcl_NewIntObj(wmPtr->minWidth);
	results[1] = Tcl_NewIntObj(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;
    }
2885
2886
2887
2888
2889
2890
2891
2892

2893
2894
2895
2896
2897
2898
2899
2888
2889
2890
2891
2892
2893
2894

2895
2896
2897
2898
2899
2900
2901
2902







-
+








    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));
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(curValue));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
	/*
3005
3006
3007
3008
3009
3010
3011
3012

3013
3014
3015
3016
3017
3018
3019
3008
3009
3010
3011
3012
3013
3014

3015
3016
3017
3018
3019
3020
3021
3022







-
+







    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;
    int cmdLength;

    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	/*
3071
3072
3073
3074
3075
3076
3077
3078

3079
3080
3081
3082
3083
3084
3085
3074
3075
3076
3077
3078
3079
3080

3081
3082
3083
3084
3085
3086
3087
3088







-
+







	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = TkGetStringFromObj(objv[4], &cmdLength);
    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);
3121
3122
3123
3124
3125
3126
3127
3128
3129


3130
3131
3132
3133
3134
3135
3136
3124
3125
3126
3127
3128
3129
3130


3131
3132
3133
3134
3135
3136
3137
3138
3139







-
-
+
+







    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));
	results[0] = Tcl_NewBooleanObj(!(wmPtr->flags&WM_WIDTH_NOT_RESIZABLE));
	results[1] = Tcl_NewBooleanObj(!(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;
    }
3331
3332
3333
3334
3335
3336
3337
3338

3339
3340
3341
3342
3343
3344
3345
3334
3335
3336
3337
3338
3339
3340

3341
3342
3343
3344
3345
3346
3347
3348







-
+







	    return TCL_ERROR;
	}
	if (index == OPT_ISABOVE) {
	    result = index1 > index2;
	} else { /* OPT_ISBELOW */
	    result = index1 < index2;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
	return TCL_OK;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
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







+















-
-
+
+







    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 ?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);
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->title = (char *)ckalloc(length + 1);
	strcpy(wmPtr->title, argv3);

	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    UpdateTitle(winPtr);
	}
    }
    return TCL_OK;
3526
3527
3528
3529
3530
3531
3532
3533

3534
3535
3536
3537
3538

3539
3540
3541
3542
3543
3544
3545
3530
3531
3532
3533
3534
3535
3536

3537
3538
3539
3540
3541

3542
3543
3544
3545
3546
3547
3548
3549







-
+




-
+







    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?");
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (containerPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) containerPtr));
	    Tcl_SetObjResult(interp, TkNewWindowObj((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
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
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







-
+






-
+


-
+







	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",
		    "can't make \"%s\" a master: 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) {
	    w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    "setting \"%s\" as master creates a transient/master cycle",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}

	if (containerPtr != wmPtr->containerPtr) {
3811
3812
3813
3814
3815
3816
3817
3818

3819
3820
3821
3822
3823
3824
3825
3826
3815
3816
3817
3818
3819
3820
3821

3822

3823
3824
3825
3826
3827
3828
3829







-
+
-







	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
	    && ((wmPtr->sizeHintsFlags & PBaseSize) == PBaseSize)) {
		    == (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
3843
3844
3845
3846
3847
3848
3849
3850

3851
3852
3853
3854
3855
3856
3857
3846
3847
3848
3849
3850
3851
3852

3853
3854
3855
3856
3857
3858
3859
3860







-
+







     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    wmPtr->sizeHintsFlags |= PBaseSize;
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

3902
3903
3904
3905
3906
3907
3908
3909

3910
3911
3912
3913
3914
3915
3916
3905
3906
3907
3908
3909
3910
3911

3912
3913
3914
3915
3916
3917
3918
3919







-
+







    }

    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
    wmPtr->sizeHintsFlags &= ~PBaseSize;
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
4870
4871
4872
4873
4874
4875
4876
4877

4878
4879
4880
4881
4882
4883
4884
4873
4874
4875
4876
4877
4878
4879

4880
4881
4882
4883
4884
4885
4886
4887







-
+







    hintsPtr->width_inc = wmPtr->widthInc;
    hintsPtr->height_inc = wmPtr->heightInc;
    hintsPtr->min_aspect.x = wmPtr->minAspect.x;
    hintsPtr->min_aspect.y = wmPtr->minAspect.y;
    hintsPtr->max_aspect.x = wmPtr->maxAspect.x;
    hintsPtr->max_aspect.y = wmPtr->maxAspect.y;
    hintsPtr->win_gravity = wmPtr->gravity;
    hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize;
    hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize | PResizeInc;

    /*
     * If the window isn't supposed to be resizable, then set the minimum and
     * maximum dimensions to be the same.
     */

    if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
5457
5458
5459
5460
5461
5462
5463
5464
5465


5466
5467
5468
5469
5470
5471
5472
5460
5461
5462
5463
5464
5465
5466


5467
5468
5469
5470
5471
5472
5473
5474
5475







-
-
+
+








    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);
	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));
6458
6459
6460
6461
6462
6463
6464
6465

6466
6467
6468
6469
6470
6471
6472
6461
6462
6463
6464
6465
6466
6467

6468
6469
6470
6471
6472
6473
6474
6475







-
+








    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]);
	    hPtr = Tcl_FindHashEntry(&table, (char *)children[i]);
	    if (hPtr != NULL) {
		childWinPtr = (TkWindow *)Tcl_GetHashValue(hPtr);
		*window_ptr++ = childWinPtr;
	    }
	}

	/*
6941
6942
6943
6944
6945
6946
6947

6948

6949
6950
6951
6952
6953
6954
6955
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960







+

+







	atts.save_under = True;
	if (typeFlag == TK_MAKE_MENU_DROPDOWN) {
	    typeObj = Tcl_NewStringObj("dropdown_menu", -1);
	} else {
	    typeObj = Tcl_NewStringObj("popup_menu", -1);
	}
    }
    Tcl_IncrRefCount(typeObj);
    SetNetWmType((TkWindow *)tkwin, typeObj);
    Tcl_DecrRefCount(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
     * overrideredirect" command will see it.
     */
Changes to unix/tkUnixXId.c.
1
2
3
4
5
6
7
8
9
10
11

































12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51











+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







/*
 * 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_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. */
{
    /*
     * This does nothing, because the XC-MISC extension takes care of
     * freeing XIDs for us.  It has been a standard X11 extension for
     * about 15 years as of 2008.  Keith Packard and another X.org
     * developer suggested that we remove the previous code that used:
     * #define XLIB_ILLEGAL_ACCESS.
     */
}


/*
 *----------------------------------------------------------------------
 *
 * Tk_GetPixmap --
 *
Changes to win/Makefile.in.
66
67
68
69
70
71
72
73



74
75

76
77
78
79
80
81
82
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85








+
+
+

-
+








# 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)
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@

122
123
124
125
126
127
128


129
130
131
132
133
134

135
136
137
138
139
140
141
142



143
144
145
146
147
148
149
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144



145
146
147
148
149
150
151
152
153
154







+
+





-
+





-
-
-
+
+
+







TCL_GENERIC_NATIVE		= $(shell $(CYGPATH) '$(TCL_GENERIC_DIR)')
TCL_PLATFORM_NATIVE		= $(shell $(CYGPATH) '$(TCL_PLATFORM_DIR)')
TCL_SRC_DIR_NATIVE		= $(shell $(CYGPATH) '$(TCL_SRC_DIR)')

DLLSUFFIX		= @DLLSUFFIX@
LIBSUFFIX		= @LIBSUFFIX@
EXESUFFIX		= @EXESUFFIX@
VER			= @TK_MAJOR_VERSION@@TK_MINOR_VERSION@
DOTVER			= @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@

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}
TEST_LIB_FILE		= @LIBPREFIX@tktest$(VER)${DLLSUFFIX}.a

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
TKTEST			= tktest${EXESUFFIX}
CAT32			= cat32${EXESUFFIX}
MAN2TCL			= man2tcl${EXESUFFIX}

@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
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191
192
193
194


195
196
197
198
199
200
201
202
203
204
205
206


207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222







-
+










-
+










-
-












-
-
+
+







-







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
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@ @TCL_DEFS@
AC_FLAGS	= @EXTRA_CFLAGS@ @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
NO_DEPRECATED_FLAGS	=
#NO_DEPRECATED_FLAGS	= -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

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
310
311
312
313
314
315
316

317
318
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342







-



-
















-







	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) \
433
434
435
436
437
438
439
440
441


442
443
444
445


446
447
448

449
450
451
452
453

454
455
456

457
458
459
460
461
462
463
432
433
434
435
436
437
438


439
440
441
442


443
444
445
446

447
448
449
450
451

452
453
454

455
456
457
458
459
460
461
462







-
-
+
+


-
-
+
+


-
+




-
+


-
+







# 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)
	$(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" \
	$(TESTFLAGS) | ./$(CAT32)

test-ttk: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32)
	$(SHELL_ENV) $(WINE) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \
	$(TESTFLAGS) | $(WINE) ./$(CAT32)
	$(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \
	$(TESTFLAGS) | ./$(CAT32)

runtest: binaries $(TKTEST) $(TEST_DLL_FILE)
	$(SHELL_ENV) $(WINE) ./$(TKTEST) $(TESTFLAGS) $(SCRIPT)
	$(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) $(WINE) ./$(WISH) $(SCRIPT)
	$(SHELL_ENV) ./$(WISH) $(SCRIPT)

demo: $(WISH)
	$(SHELL_ENV) $(WINE) ./$(WISH) $(ROOT_DIR)/library/demos/widget
	$(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
480
481
482
483
484
485
486

487
488
489

490
491

492
493
494
495
496
497
498
499







-
+


-
+

-
+







		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 {![package vsatisfies [package provide Tcl] 8.6.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]] Tk]";\
	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)]] Tk]";\
	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)"; \
621
622
623
624
625
626
627









628
629
630
631
632
633
634
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642







+
+
+
+
+
+
+
+
+







	$(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)

$(TOP_DIR)/manifest.uuid:
	printf "git-" >$(TOP_DIR)/manifest.uuid
	(cd $(TOP_DIR); git rev-parse HEAD >>$(TOP_DIR)/manifest.uuid || printf "unknown" >$(TOP_DIR)/manifest.uuid)

tkUuid.h:	$(TOP_DIR)/manifest.uuid
	echo "#define TK_VERSION_UUID \\" >$@
	cat $(TOP_DIR)/manifest.uuid >>$@
	echo "" >>$@

# 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)

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
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







+
+
+
+
+
+









+
+
+




-








tkWinTest.$(OBJEXT): tkWinTest.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkSquare.$(OBJEXT): tkSquare.c
	$(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME)

tkStubLib.$(OBJEXT): tkStubLib.c
	$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ @DEPARG@ $(CC_OBJNAME)

ttkStubLib.$(OBJEXT): ${TTK_DIR}/ttkStubLib.c
	$(CC) -c $(CC_SWITCHES) @CFLAGS_NOLTO@ @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)

tkWindow.$(OBJEXT): ${GENERIC_DIR}/tkWindow.c configure Makefile tkUuid.h
	$(CC) -c $(CC_SWITCHES) -I. -DBUILD_tk @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
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
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







-
+
+



-
+



















-
+








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
	$(RM) *.pch *.ilk *.pdb *.zip
	$(RMDIR) *.vfs

distclean: clean
	$(RM) Makefile config.status config.cache config.log tkConfig.sh \
		wish.exe.manifest
		wish.exe.manifest tkUuid.h

Makefile: $(SRC_DIR)/Makefile.in
	./config.status

#
# Regenerate the stubs files.
#

$(GENERIC_DIR)/tkStubInit.c: $(GENERIC_DIR)/tk.decls \
		$(GENERIC_DIR)/tkInt.decls
	@echo "Warning: tkStubInit.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) "$(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" \
	$(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

1
2
3
4
5
6
7
8
-
+







Tk 8.7 for Windows
Tk 8.6 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.
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
1
2

3
4


5


6
7



8
9
10
11

12


13
14
15

16
17
18



19


20



21

22














































23



24
25







26


27











28






29

30



31


32



33



34
35
36
37
38


39



40
41



42
















































43







44


















45
46





























47






































48















































































49


50

51






























































52

53
54
55
56
57

58
59
60
61
62
63





64
65

66
67
68



69
70
71
72




73







74
75
76
77


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99




100
101
102
103
104


105
106
107




108
109
110
111




112
113
114
115
116
117
118



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

171
172
173


174
175
176
177




178
179


180
181
182
183
184
185

186



187


188


189



190
191
192
193


194

195
196


197
198
199
200


201
202


203


204



205
206
207


208

209
210
211
212
213

214
215

216

217
218

219
220
221
222
223
224


225
226
227
228
229
230
231
232
233
234
235
236
237
238


239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254

255

256
257
258
259
260
261
262
263
264
265
266
267





268
269
270
271
272

273
274
275
276
277

278
279
280

281
282
283

284
285
286
287

288
289
290
291


292
293
294
295
296
297

298
299
300

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.69.
# Generated by GNU Autoconf 2.59 for tk 8.6.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
# 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. ##
## -------------------- ##
## --------------------- ##
## M4sh Initialization.  ##
## --------------------- ##

# Be more Bourne compatible
# Be Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
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
  # Zsh 3.x and 4.x performs 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 #(
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
  *posix*) :
    set -o posix ;; #(
  set -o posix
  *) :
     ;;
esac
fi

DUALCASE=1; export DUALCASE # for MKS sh

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


# Support unset when possible.
if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
# 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"

  as_unset=unset
# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
else
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

  as_unset=false
     ;;
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"
# Work around bugs in pre-3.0 UWIN ksh.
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
$as_unset 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
for as_var in \
LANGUAGE=C
export LANGUAGE

  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

  LC_TELEPHONE LC_TIME
# 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; }

do
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 :

  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&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
    eval $as_var=C; export $as_var
  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

    $as_unset $as_var

      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
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
done
    test -z "$as_dirs" || eval "mkdir $as_dirs"
  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"


# Required to use basename.
} # 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 &&
if expr a : '\(a\)' >/dev/null 2>&1; then
   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
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

# Name of the executable.
as_me=`$as_basename -- "$0" ||
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	 X"$0" : 'X\(/\)$' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  /^X\/\(\/\).*/{
	    s//\1/
	    q
	  }
  	  /^X\/\(\/\).*/{ s//\1/; q; }
  	  s/.*/./; 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_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'"' || {
  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"  || {
  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
  sed -n '
  # Find who we are.  Look in the path if we contain no path at all
  # relative or not.
  case $0 in
    p
    /[$]LINENO/=
  ' <$as_myself |
    sed '
    *[\\/]* ) as_myself=$0 ;;
    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
      s/[$]LINENO.*/&-/
      t lineno
      b
      :lineno
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done

       ;;
  esac
      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
  # 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/-\n.*//
      s,-$,,
      s,^['$as_cr_digits']*\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; }
  chmod +x $as_me.lineno ||
    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
   { (exit 1); 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"
  # original and so on.  Autoconf is especially sensible 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
case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *c*,-n*) ECHO_N= ECHO_C='
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
' ECHO_T='	' ;;
  esac;;
*)
  ECHO_N='-n';;
  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac

rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
if expr a : '\(a\)' >/dev/null 2>&1; then
  rm -f conf$$.dir/conf$$.file
  as_expr=expr
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
  as_expr=false
fi

rm -f conf$$ conf$$.exe conf$$.file
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
  # We could just check for DJGPP; but this test a) works b) is more generic
    # 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.
  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
    # 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'
  if test -f conf$$.exe; then
    # Don't use ln at all; we don't have any links
    as_ln_s='cp -p'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
    as_ln_s='ln -s'
  fi
elif ln conf$$.file conf$$ 2>/dev/null; then
  as_ln_s=ln
else
  as_ln_s='cp -pR'
  as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rm -f conf$$ conf$$.exe conf$$.file
rmdir conf$$.dir 2>/dev/null

if mkdir -p . 2>/dev/null; then
  as_mkdir_p='mkdir -p "$as_dir"'
  as_mkdir_p=:
else
  test -d ./-p && rmdir ./-p
  as_mkdir_p=false
fi

as_test_x='test -x'
as_executable_p=as_fn_executable_p
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"
test -n "$DJDIR" || exec 7<&0 </dev/null
exec 6>&1

# CDPATH.
$as_unset CDPATH


# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
# 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_clean_files=
ac_config_libobj_dir=.
LIBOBJS=
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=
PACKAGE_TARNAME=
PACKAGE_VERSION=
PACKAGE_STRING=
PACKAGE_BUGREPORT=
PACKAGE_NAME='tk'
PACKAGE_TARNAME='tk'
PACKAGE_VERSION='8.6'
PACKAGE_STRING='tk 8.6'
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
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef STDC_HEADERS
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# if HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_INTTYPES_H
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#else
# if HAVE_STDINT_H
#  include <stdint.h>
# endif
#endif
#ifdef HAVE_UNISTD_H
#if HAVE_UNISTD_H
# include <unistd.h>
#endif"

ac_subst_vars='LTLIBOBJS
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 CFLAGS_NOLTO 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 EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW TK_RES STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TK_SHARED_BUILD 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 RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS 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
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
333
334
335
336
337
338
339

340
341
342

343

344
345
346
347
348
349


350







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.
# (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='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
infodir='${datarootdir}/info'
infodir='${prefix}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'
psdir='${docdir}'
libdir='${exec_prefix}/lib'
localedir='${datarootdir}/locale'
mandir='${datarootdir}/man'
mandir='${prefix}/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
    eval "$ac_prev=\$ac_option"
    ac_prev=
    continue
  fi

  case $ac_option in
  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
  *=)   ac_optarg= ;;
  *)    ac_optarg=yes ;;
  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case $ac_dashdash$ac_option in
  case $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)
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
382
383
384
385
386
387
388

389
390

391




392




393
394
395

396
397


398
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)
  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
    ac_prev=datadir ;;
  -datadir=* | --datadir=* | --datadi=* | --datad=*)
  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
    datadir=$ac_optarg ;;

  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
  | --dataroo | --dataro | --datar)
  | --da=*)
    ac_prev=datarootdir ;;
  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;
    datadir=$ac_optarg ;;

  -disable-* | --disable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    ac_feature=`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"
    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
    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 ;;

   { (exit 1); exit 1; }; }
  -docdir | --docdir | --docdi | --doc | --do)
    ac_prev=docdir ;;
  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
    docdir=$ac_optarg ;;

    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
    ac_prev=dvidir ;;
  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;
    eval "enable_$ac_feature=no" ;;

  -enable-* | --enable-*)
    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    ac_feature=`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
    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
      *"
"enable_$ac_useropt"
"*) ;;
      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
      *) ac_optarg=yes ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval enable_$ac_useropt=\$ac_optarg ;;
    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
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 ;;

  -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 ;;

974
975
976
977
978
979
980
981
982
983
984
985
986
987


988
989
990


991
992
993
994
995
996
997
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 ;;

  -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)
  | --localstate | --localstat | --localsta | --localst \
  | --locals | --local | --loca | --loc | --lo)
    ac_prev=localstatedir ;;
  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
  | --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
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 ;;

  -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=* \
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
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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    ac_package=`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
    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
      *"
"with_$ac_useropt"
"*) ;;
      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
      *) ac_optarg=yes ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=\$ac_optarg ;;
    eval "with_$ac_package='$ac_optarg'" ;;

  -without-* | --without-*)
    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    ac_package=`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"
    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
      { echo "$as_me: error: invalid package name: $ac_package" >&2
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
   { (exit 1); exit 1; }; }
    ac_package=`echo $ac_package | sed 's/-/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
    eval "with_$ac_package=no" ;;
"*) ;;
      *) 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"
  -*) { 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.
    case $ac_envvar in #(
      '' | [0-9]* | *[!_$as_cr_alnum]* )
      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    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.
    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    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}"
      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"
  { echo "$as_me: error: missing argument to $ac_option" >&2
fi

   { (exit 1); exit 1; }; }
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 \
# Be sure to have absolute paths.
for ac_var in exec_prefix prefix
		datadir sysconfdir sharedstatedir localstatedir includedir \
		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir
do
  eval ac_val=\$$ac_var
  eval ac_val=$`echo $ac_var`
  # Remove trailing slashes.
  case $ac_val in
    */ )
    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;
    *)  { 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 directory names.
# 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
    [\\/$]* | ?:[\\/]* )  continue;;
    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
    [\\/$]* | ?:[\\/]* ) ;;
    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
   { (exit 1); exit 1; }; };;
  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
    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


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\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
  # 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; }
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{
  	  /^X\(\/\/\)$/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
  	  /^X\(\/\).*/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
  	  s/.*/./; q'`
  srcdir=$ac_confdir
  if test ! -r "$srcdir/$ac_unique_file"; then
  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
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
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}
(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
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.
\`configure' configures tk 8.6 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
  -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]
			  [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]
			  [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]
  --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]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --infodir=DIR          info documentation [PREFIX/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --mandir=DIR           man documentation [PREFIX/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

  case $ac_init_help in
     short | recursive ) echo "Configuration of tk 8.6:";;
   esac
  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-threads        build with threads (default: on)
  --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>
  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>
  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.

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.
  ac_popdir=`pwd`
  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
    test -d $ac_dir || continue
    ac_builddir=.

case "$ac_dir" in
if test "$ac_dir" != .; then
.) 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|/||'`
  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'`
  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
else
  ac_dir_suffix= ac_top_builddir=
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
fi

case $srcdir in
  .)  # We are building in place.
  .)  # No --srcdir option.  We are building in place.
    ac_srcdir=.
    if test -z "$ac_top_builddir"; then
    ac_top_srcdir=$ac_top_builddir_sub
    ac_abs_top_srcdir=$ac_pwd ;;
  [\\/]* | ?:[\\/]* )  # Absolute name.
       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
    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 ;;
  *) # 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_top_srcdir$ac_dir_suffix
  .) 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" || { 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
    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
      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi || ac_status=$?
    cd "$ac_pwd" || { ac_status=$?; break; }
      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi
    cd $ac_popdir
  done
fi

test -n "$ac_init_help" && exit $ac_status
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
  cat <<\_ACEOF
configure
generated by GNU Autoconf 2.69
tk configure 8.6
generated by GNU Autoconf 2.59

Copyright (C) 2012 Free Software Foundation, Inc.
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
  exit 0
fi

exec 5>config.log
## ------------------------ ##
## 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
cat >&5 <<_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
It was created by tk $as_me 8.6, which was
generated by GNU Autoconf 2.59.  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`
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=.
    $as_echo "PATH: $as_dir"
  done
  echo "PATH: $as_dir"
done
IFS=$as_save_IFS

} >&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
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=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
    2)
      as_fn_append ac_configure_args1 " '$ac_arg'"
      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
      as_fn_append ac_configure_args " '$ac_arg'"
      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
      # Get rid of the leading space.
      ac_sep=" "
      ;;
    esac
  done
done
{ ac_configure_args0=; unset ac_configure_args0;}
{ ac_configure_args1=; unset ac_configure_args1;}
$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: 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.
# 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
    $as_echo "## ---------------- ##
## ---------------- ##
## Cache variables. ##
## ---------------- ##"
## ---------------- ##
_ASBOX
    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=\ *)
    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"
      ;; #(
	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
      ;;
    *)
      sed -n \
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
      ;;
    esac |
    esac;
    sort
)
}
    echo

    cat <<\_ASBOX
    $as_echo "## ----------------- ##
## ----------------- ##
## Output variables. ##
## ----------------- ##"
## ----------------- ##
_ASBOX
    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=\$$ac_var
      eval ac_val=$`echo $ac_var`
      case $ac_val in
      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      $as_echo "$ac_var='\''$ac_val'\''"
      echo "$ac_var='"'"'$ac_val'"'"'"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      cat <<\_ASBOX
      $as_echo "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
## ------------- ##
## Output files. ##
## ------------- ##
_ASBOX
      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=\$$ac_var
	eval ac_val=$`echo $ac_var`
	case $ac_val in
	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	$as_echo "$ac_var='\''$ac_val'\''"
	echo "$ac_var='"'"'$ac_val'"'"'"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      cat <<\_ASBOX
      $as_echo "## ----------- ##
## ----------- ##
## confdefs.h. ##
## ----------- ##"
## ----------- ##
_ASBOX
      echo
      cat confdefs.h
      sed "/^$/d" confdefs.h | sort
      echo
    fi
    test "$ac_signal" != 0 &&
      $as_echo "$as_me: caught signal $ac_signal"
    $as_echo "$as_me: exit $exit_status"
      echo "$as_me: caught signal $ac_signal"
    echo "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core core.conftest.* &&
    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
  rm -f core *.core &&
  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
' 0
     ' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
  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 -f -r conftest* confdefs.h

$as_echo "/* confdefs.h */" > confdefs.h
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

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.
# Prefer explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
if test -z "$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
  if test "x$prefix" != xNONE; then
    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
  ac_site_file2=$prefix/etc/config.site
else
  ac_site_file1=$ac_default_prefix/share/config.site
  else
    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
  ac_site_file2=$ac_default_prefix/etc/config.site
fi
for ac_site_file in "$ac_site_file1" "$ac_site_file2"
  fi
fi
for ac_site_file in $CONFIG_SITE; do
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;}
  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" \
    . "$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;}
  # 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";;
      [\\/]* | ?:[\\/]* ) . $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;}
  { 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 $ac_precious_vars; do
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
  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;}
      { 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)
      { $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;}
      { 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
	# 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;}
	{ 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;}
	  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;}
	{ 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=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
      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.
      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
      *) ac_configure_args="$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
  { 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
## -------------------- ##
## 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_VERSION=8.6
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=7
TK_PATCH_LEVEL="a4"
TK_MINOR_VERSION=6
TK_PATCH_LEVEL=".16"
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
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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}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
  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.
  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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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

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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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.exe
  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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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.exe
  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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}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
  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; }
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:" \
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
     "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
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
  (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=$?
  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; }
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }
done

cat confdefs.h - <<_ACEOF >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.  */

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"
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.
{ $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[^ ]*//'`

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
# 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
  (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
  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.
# Autoconf.
for ac_file in $ac_files ''
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 | *.map | *.inf | *.dSYM | *.o | *.obj )
    *.$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;;
    *.* )
	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
	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
	# 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
  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
{ { 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
{ $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; }
  fi
fi
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
ac_exeext=$ac_cv_exeext

rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
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

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
echo "$as_me:$LINENO: checking for suffix of executables" >&5
echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&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
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>&5
  ac_status=$?
  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  test $ac_status = 0; }; then :
  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 | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
    *.$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
  { { $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; }
  { { 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 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_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
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
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 confdefs.h - <<_ACEOF >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.  */

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
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&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
  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
  test -f "$ac_file" || continue;
  case $ac_file in
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
       break;;
  esac
done
else
  $as_echo "$as_me: failed program was:" >&5
  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; }
{ { 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
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
$as_echo "$ac_cv_objext" >&6; }
echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
echo "${ECHO_T}$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
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 confdefs.h - <<_ACEOF >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.  */

int
main ()
{
#ifndef __GNUC__
       choke me
#endif

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
if ac_fn_c_try_compile "$LINENO"; then :
  (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
ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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
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`
  GCC=yes
else
  GCC=
fi
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
CFLAGS="-g"
{ $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
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
  ac_save_c_werror_flag=$ac_c_werror_flag
  cat >conftest.$ac_ext <<_ACEOF
   ac_c_werror_flag=yes
   ac_cv_prog_cc_g=no
   CFLAGS="-g"
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* 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
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_prog_cc_g=yes
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
else
  CFLAGS=""
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
int
main ()
{

  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

  (exit $ac_status); } &&
else
  ac_c_werror_flag=$ac_save_c_werror_flag
	 { ac_try='test -z "$ac_c_werror_flag"
	 CFLAGS="-g"
	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

int
main ()
			 || 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
  ;
  return 0;
}
  (exit $ac_status); }; }; then
  ac_cv_prog_cc_g=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_prog_cc_g=yes
ac_cv_prog_cc_g=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
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
{ $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
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_c89=no
  ac_cv_prog_cc_stdc=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >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.  */
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
struct stat;
#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
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 -std is added to get
   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 -std.  */
   that's true only with -std1.  */
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
# Don't try gcc -ansi; that turns off useful extensions and
# breaks some systems' header files.
for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
# 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
  if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_prog_cc_c89=$ac_arg
  (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 core conftest.err conftest.$ac_objext
rm -f conftest.err conftest.$ac_objext
  test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
rm -f conftest.$ac_ext conftest.$ac_objext
CC=$ac_save_CC

fi
# AC_CACHE_VAL
case "x$ac_cv_prog_cc_c89" in

case "x$ac_cv_prog_cc_stdc" 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; } ;;
  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_c89"
    CC="$CC $ac_cv_prog_cc_stdc" ;;
    { $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 :


# 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


{ $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
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 confdefs.h - <<_ACEOF >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.  */
#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
if ac_fn_c_try_compile "$LINENO"; then :
  ac_cv_c_inline=$ac_kw
  (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 core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
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
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
{ $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; }
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 ${ac_cv_prog_CPP+:} false; then :
  $as_echo_n "(cached) " >&6
  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 confdefs.h - <<_ACEOF >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.  */
#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 ac_fn_c_try_cpp "$LINENO"; 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.i conftest.$ac_ext
rm -f conftest.err conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # OK, works on sane cases.  Now check whether non-existent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >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.  */
#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 ac_fn_c_try_cpp "$LINENO"; 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.i conftest.$ac_ext
rm -f conftest.err 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 :
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
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
$as_echo "$CPP" >&6; }
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 confdefs.h - <<_ACEOF >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.  */
#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 ac_fn_c_try_cpp "$LINENO"; 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.i conftest.$ac_ext
rm -f conftest.err conftest.$ac_ext

  # OK, works on sane cases.  Now check whether nonexistent headers
  # OK, works on sane cases.  Now check whether non-existent headers
  # can be detected and how.
  cat confdefs.h - <<_ACEOF >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.  */
#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 ac_fn_c_try_cpp "$LINENO"; 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.i conftest.$ac_ext
rm -f conftest.err 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 :

rm -f 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; }
  { { 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


{ $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
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 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
  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
    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"
    then ac_cv_prog_egrep='grep -E'
      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

    else ac_cv_prog_egrep='egrep'
      $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
    fi
else
  ac_cv_path_GREP=$GREP
fi

echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
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"


echo "${ECHO_T}$ac_cv_prog_egrep" >&6
 EGREP=$ac_cv_prog_egrep
{ $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
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 confdefs.h - <<_ACEOF >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.  */
#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
if ac_fn_c_try_compile "$LINENO"; then :
  (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
ac_cv_header_stdc=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
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 confdefs.h - <<_ACEOF >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.  */
#include <string.h>

_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  $EGREP "memchr" >/dev/null 2>&1; then :

  $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
  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 :

  $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 :
  if test "$cross_compiling" = yes; then
  :
else
  cat confdefs.h - <<_ACEOF >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.  */
#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
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))
      return 2;
  return 0;
      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
if ac_fn_c_try_run "$LINENO"; then :

  (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
ac_cv_header_stdc=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
  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; }
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
$as_echo "#define STDC_HEADERS 1" >>confdefs.h
#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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $AR" >&5
echo "${ECHO_T}$AR" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
echo "${ECHO_T}$ac_ct_AR" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}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
  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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $RANLIB" >&5
echo "${ECHO_T}$RANLIB" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
echo "${ECHO_T}$ac_ct_RANLIB" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}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
  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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $RC" >&5
echo "${ECHO_T}$RC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $ac_ct_RC" >&5
echo "${ECHO_T}$ac_ct_RC" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}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
  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; }
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=`$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
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
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
  echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
  SET_MAKE=
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
  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=yes
fi;

    if test "$tcl_ok" = "yes"; then
	echo "$as_me:$LINENO: result: yes (default)" >&5
echo "${ECHO_T}yes (default)" >&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" >&5
echo "${ECHO_T}no" >&6
    fi



#--------------------------------------------------------------------
# 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.
    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 "${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; }
	echo "$as_me:$LINENO: result: shared" >&5
echo "${ECHO_T}shared" >&6
	SHARED_BUILD=1
    else
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
	echo "$as_me:$LINENO: result: static" >&5
echo "${ECHO_T}static" >&6
	SHARED_BUILD=0

cat >>confdefs.h <<\_ACEOF
$as_echo "#define STATIC_BUILD 1" >>confdefs.h
#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 was given.
if test "${with_tcl+set}" = set; then :
  withval=$with_tcl; with_tclconfig="${withval}"
fi
# Check whether --with-tcl or --without-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
	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
			    { $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;}
			    { 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
		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 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
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







+
-
+
+



-
-
+
+




-
-
+
+


-
-
+
+


-
-
+
+












-
-
-
+
+
+


+
+
+
+
+
+
+
+



















-
-

+
+
+
-
-
-
+
+
+
+

-
-
-
-
+
+
+
+
+
+
+
-
+







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





-
-
-
-
-
+
+
+
+
+
+


-
+
+
+

+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+



+
-
+
+




-
-
-
-
+
+
+
+









-
-
+
+

-
+



-
+
-






-
-
+
+

-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-

-
-
-
-
-
-
-
-
-
-

-
-



-
+




-
-
-
-
+
+
+
+

-
+
+
+
+
+














+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+

-
+


-
-
+
+










+
+
+
+
+
+
+







	    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
	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 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}"
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
	    echo "$as_me:$LINENO: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
echo "${ECHO_T}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; }
    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
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
$as_echo "loading" >&6; }
	echo "$as_me:$LINENO: result: loading" >&5
echo "${ECHO_T}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; }
	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}
	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}\""

















if test "${TCL_MAJOR_VERSION}" -lt 9 ; then
if test "${TCL_MAJOR_VERSION}" != "${TK_MAJOR_VERSION}"; then
    { { echo "$as_me:$LINENO: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&5
    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
echo "$as_me: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&2;}
   { (exit 1); exit 1; }; }
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
if test "${TCL_MINOR_VERSION}" -lt "${TK_MINOR_VERSION}"; then
    { { echo "$as_me:$LINENO: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&5
echo "$as_me: error: ${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}." >&2;}
fi
   { (exit 1); exit 1; }; }
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
    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
fi;
    echo "$as_me:$LINENO: result: $do64bit" >&5
echo "${ECHO_T}$do64bit" >&6

    # Cross-compiling options for Windows/CE builds
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
$as_echo "$do64bit" >&6; }

    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
$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
#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
{ $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
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_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  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"
    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
    break 2
  fi
done
  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; }
  echo "$as_me:$LINENO: result: $CYGPATH" >&5
echo "${ECHO_T}$CYGPATH" >&6
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


  echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
    # 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
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.
    # which requires x86|amd64|arm64|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
      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 confdefs.h - <<_ACEOF >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.  */

	    #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
if ac_fn_c_try_compile "$LINENO"; then :
  (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
ac_cv_cross=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
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-${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"
	    ;;
	    arm64|aarch64)
		CC="aarch64-w64-mingw32-${CC}"
		LD="aarch64-w64-mingw32-ld"
		AR="aarch64-w64-mingw32-ar"
		RANLIB="aarch64-w64-mingw32-ranlib"
		RC="aarch64-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"
	    ;;
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
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







-
-
+
+


-
+


-
-
-
-
+
+
+
+

-
-
+
+







-
+

-
+







-
-
-
-
+
+
+
+

-
+
+
+
+
+














+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+

-
+


-
-
+
+

+
-
+
+
+
+
+



-
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
-
-
+













+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+

-
-
+
+


-
-
+
+






+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+




















-
-
+
+


-
+


-
-
+
+



+
+
-
-
+
+
+





-
+







-
+


-
-
-
+
+
+






-
+








-
+








    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; }
	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\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
  { (eval echo "$as_me:$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; }
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } ; then
	    echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
	    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='"$<"'
	DEPARG='"$<"'
    else
        DEPARG='"$(shell $(CYGPATH) $<)"'
	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
	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 confdefs.h - <<_ACEOF >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.  */

		#ifdef _WIN32
		    #error win32
		#endif

int
main ()
{

  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
if ac_fn_c_try_compile "$LINENO"; then :
  (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
ac_cv_win32=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
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
	    as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5
echo "$as_me: error: ${CC} cannot produce win32 executables." >&2;}
   { (exit 1); exit 1; }; }
	fi
	if test "$do64bit" != "arm64"; then
	    extra_cflags="$extra_cflags -DHAVE_CPUID=1"
	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
	echo "$as_me:$LINENO: checking for working -municode linker flag" >&5
echo $ECHO_N "checking for working -municode linker flag... $ECHO_C" >&6
if test "${ac_cv_municode+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&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
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
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

cat confdefs.h >>conftest.$ac_ext
} # ac_fn_c_try_link
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

	#include <windows.h>
	int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}

int
main ()
{

  ;
  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
if ac_fn_c_try_link "$LINENO"; then :
  (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
  ac_cv_municode=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

  ac_cv_municode=no
ac_cv_municode=no
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext
rm -f 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; }
echo "$as_me:$LINENO: result: $ac_cv_municode" >&5
echo "${ECHO_T}$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
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto"
	echo "$as_me:$LINENO: checking for working -fno-lto" >&5
echo $ECHO_N "checking for working -fno-lto... $ECHO_C" >&6
if test "${ac_cv_nolto+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_nolto=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_nolto=no
    fi
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

fi
echo "$as_me:$LINENO: result: $ac_cv_nolto" >&5
echo "${ECHO_T}$ac_cv_nolto" >&6
	CFLAGS=$hold_cflags
	if test "$ac_cv_nolto" = "yes" ; then
	    CFLAGS_NOLTO="-fno-lto"
	else
	    CFLAGS_NOLTO=""
	fi
    fi

    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--enable-auto-image-base"
    echo "$as_me:$LINENO: checking for working --enable-auto-image-base" >&5
echo $ECHO_N "checking for working --enable-auto-image-base... $ECHO_C" >&6
if test "${ac_cv_enable_auto_image_base+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_enable_auto_image_base=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_enable_auto_image_base=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext

fi
echo "$as_me:$LINENO: result: $ac_cv_enable_auto_image_base" >&5
echo "${ECHO_T}$ac_cv_enable_auto_image_base" >&6
    CFLAGS=$hold_cflags
    if test "$ac_cv_enable_auto_image_base" = "yes" ; then
	extra_ldflags="$extra_ldflags -Wl,--enable-auto-image-base"
    fi

    { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5
$as_echo_n "checking compiler flags... " >&6; }
    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="-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; }
	    echo "$as_me:$LINENO: result: using static flags" >&5
echo "${ECHO_T}using static flags" >&6
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }
	    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
		as_fn_error $? "${CC} does not support the -shared option.
                You will need to upgrade to a newer version of the toolchain." "$LINENO" 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=".exe"
	    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%.a,\$@)"
	    -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=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	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 -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	CFLAGS_WARNING="-Wall -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wdeclaration-after-statement"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \$@"
	CC_EXENAME="-o \$@"

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
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







-
-
+
+
+
+
+
+
+



-
-
+
+


-
+
+
+
+
+














+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+


-
+

-
-
-
-
+
+
+
+






-
-
+
+


-
+


-
-
+
+



-
+











-
-
-
+
+
+






+
+
+




-
-
+
+















-
-
+
















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+







	#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; }
		echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
echo "${ECHO_T}   Using 64-bit $MACHINE mode" >&6
		;;
	    arm64|aarch64)
		MACHINE="ARM64"
		echo "$as_me:$LINENO: result:    Using ARM64 $MACHINE mode" >&5
echo "${ECHO_T}   Using ARM64 $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; }
		echo "$as_me:$LINENO: result:    Using IA64 $MACHINE mode" >&5
echo "${ECHO_T}   Using IA64 $MACHINE mode" >&6
		;;
	    *)
		cat confdefs.h - <<_ACEOF >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.  */

		    #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
if ac_fn_c_try_compile "$LINENO"; then :
  (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
tcl_win_64bit=no

fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
		    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
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5
$as_echo "using static flags" >&6; }
	    echo "$as_me:$LINENO: result: using static flags" >&5
echo "${ECHO_T}using static flags" >&6
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5
$as_echo "using shared flags" >&6; }
	    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=".exe"
	    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=".dll"
	LIBSUFFIX=".lib"
	LIBFLAGSUFFIX=""
	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
		    ;;
		arm64|aarch64)
		    MACHINE="ARM64"
		    ;;
		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; }
	    echo "$as_me:$LINENO: result:    Using 64-bit $MACHINE mode" >&5
echo "${ECHO_T}   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"
		    ;;
		*)
		    ;;
	esac

	if test "$do64bit" != "no" ; then
	    RC="rc"
	    CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"
	    # Do not use -O2 for Win64 - this has proved buggy in code gen.
	    CFLAGS_OPTIMIZE="-nologo -O1 ${runtime}"
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo -MACHINE:${MACHINE}"
	    LINKBIN="link"
	    # Avoid 'unresolved external symbol __security_cookie' errors.
	    # c.f. http://support.microsoft.com/?id=894573
	    LIBS="$LIBS bufferoverflowU.lib"
	else
	    RC="rc"
	    # -Od - no optimization
	    # -WX - warnings as errors
	    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"
	    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
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
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







-
+









+
-
+
+




-
-
-
-
+
+
+
+

-
+


-
+
+
+
+
+


















+
+
+
+
+
+
+
-
+
+
+
+


+
+
+
+
+
-
+

-
+
-


-

-
-
+
+


+
-
+
+









-
-
-
-
+
+
+
+

-
+
+
+
+
+
















+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+

-
+


-
-
+
+


+
-
+
+







-
-
-
-
+
+
+
+

-
+
+
+
+
+



















+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+

-
+


-
-
+
+


+
-
-
+
+
-

-
-
-
-
-
-
+
-
-





-
-
-
-
+
+
+
+

-
+
+
+
+
+













+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+

-
+


-
-
+
+


+
-
+
+










+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-
-
-
-
+
+
+
+


-
+
+
+
+
+










+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+


+
+
+
-
+

-
-
+
+

-
-
+
+


+
-
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
+
+



+
+
+
+
+
+
+
+
+
+
+
-
+

-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












-
-
-
-
-
+
+
+
+
+
+


-
+
-




+

+
-
+
+

-
-
+
+

+
-
+
+




+

-
-
+
+







+
-
+
+





+
-
+
+


+
-
+
+





-
-
+
+

-
-
+
+



+
+






-
-
-
-
-
+
+
+
+
+
+


-
+
-







-
+
+
+
+
+








-
+


















-
-
+
+





-
-
-
-
-
+
+
+
+
+



-
-
+
+

-
-
+
+




















-
-
+
+



-
-
+
+
















-

-
+


+
-
+
+
+
+







-
+


-
+



-
+








-






-
-
+
+
+
+
+
+


+
+
+
-
+
+














+








	# 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
	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
	$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h
#define TCL_CFG_DO64BIT 1
_ACEOF

    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
	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 :
  if test "$cross_compiling" = yes; then
  tcl_cv_seh=no
else
  cat confdefs.h - <<_ACEOF >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.  */

	    #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
if ac_fn_c_try_run "$LINENO"; then :
  (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
tcl_cv_seh=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
  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; }
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
$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h
#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.
	#
	{ $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
	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 confdefs.h - <<_ACEOF >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.  */

#	    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
if ac_fn_c_try_compile "$LINENO"; then :
  (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
tcl_cv_eh_disposition=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
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
$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h
#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.

	{ $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
	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 confdefs.h - <<_ACEOF >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.  */

		#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
if ac_fn_c_try_compile "$LINENO"; then :
  (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
tcl_cv_winnt_ignore_void=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
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
$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h

#define HAVE_WINNT_IGNORE_VOID 1
_ACEOF
	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
	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
	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 confdefs.h - <<_ACEOF >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.  */

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
if ac_fn_c_try_compile "$LINENO"; then :
  (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
tcl_cv_cast_to_union=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
rm -f 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; }
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
$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
#define HAVE_CAST_TO_UNION 1
_ACEOF

	fi
    fi

    # DL_LIBS is empty, but then we match the Unix version







#--------------------------------------------------------------------
# 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_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 :
$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
#-------------------------------------------

{ $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
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 confdefs.h - <<_ACEOF >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.  */
#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
if ac_fn_c_try_link "$LINENO"; then :
  (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
tcl_cv_strtoi64=no
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext
rm -f 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; }
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
$as_echo "#define NO_STRTOI64 1" >>confdefs.h
#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_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
  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
  { $as_echo "$as_me:${as_lineno-$LINENO}: xpnative theme will be unavailable" >&5
$as_echo "$as_me: xpnative theme will be unavailable" >&6;}
  { echo "$as_me:$LINENO: xpnative theme will be unavailable" >&5
echo "$as_me: xpnative theme will be unavailable" >&6;}
fi


echo "$as_me:$LINENO: checking for vssym32.h" >&5
echo $ECHO_N "checking for vssym32.h... $ECHO_C" >&6
if test "${ac_cv_header_vssym32_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.  */
ac_fn_c_check_header_compile "$LINENO" "vssym32.h" "ac_cv_header_vssym32_h" "#include <windows.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

#include <vssym32.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_vssym32_h=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_header_vssym32_h=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_header_vssym32_h" >&5
echo "${ECHO_T}$ac_cv_header_vssym32_h" >&6
if test $ac_cv_header_vssym32_h = yes; then
  cat >>confdefs.h <<\_ACEOF
#define HAVE_VSSYM32_H 1
_ACEOF

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
    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
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
$as_echo "#define NDEBUG 1" >>confdefs.h
#define NDEBUG 1
_ACEOF

	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
	echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6

	cat >>confdefs.h <<\_ACEOF
	$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h
#define TCL_CFG_OPTIMIZED 1
_ACEOF

    else
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	DBGX=g
	if test "$tcl_ok" = "yes"; then
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
$as_echo "yes (standard debugging)" >&6; }
	    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
$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h
#define TCL_MEM_DEBUG 1
_ACEOF

    fi

    if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then

cat >>confdefs.h <<\_ACEOF
$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h
#define TCL_COMPILE_DEBUG 1
_ACEOF


cat >>confdefs.h <<\_ACEOF
$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h
#define TCL_COMPILE_STATS 1
_ACEOF

    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; }
	    echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5
echo "${ECHO_T}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; }
	    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
#--------------------------------------------------------------------


    { $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
    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
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
	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 :
  $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; }
    echo "$as_me:$LINENO: result: $result" >&5
echo "${ECHO_T}$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; }
    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}\${EXESUFFIX}
    echo "$as_me:$LINENO: result: $BUILD_TCLSH" >&5
echo "${ECHO_T}$BUILD_TCLSH" >&6



    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
$as_echo_n "checking for tclsh... " >&6; }
    echo "$as_me:$LINENO: checking for tclsh" >&5
echo $ECHO_N "checking for tclsh... $ECHO_C" >&6

    if ${ac_cv_path_tclsh+:} false; then :
  $as_echo_n "(cached) " >&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"
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5
$as_echo "$TCLSH_PROG" >&6; }
	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=""
	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
$as_echo "No tclsh found on PATH" >&6; }
	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
#------------------------------------------------------------------------

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_SRC_DIR=\"`cd $srcdir/..; $CYGPATH $(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}"
 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_BUILD_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TK_LIB_FLAG}\""

eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""
TK_BUILD_STUB_LIB_SPEC="-L`pwd` ${TK_STUB_LIB_FLAG}"
eval "TK_BUILD_STUB_LIB_SPEC=\"-L`$CYGPATH $(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 "TK_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(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"
if test ${SHARED_BUILD} = 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=""
	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.`"

# X86|AMD64|IA64 for manifest








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
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







-
+



















-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
-
-
-
+
+
+
+



-
+


+
-
+

-
+
-
-
+

-

-
+


-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-
+

-
+
-
-
-
-
-
-

-
-
+
+

-
+

-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+




-


+
-
+
-
-
+
-
-
-
+
+







-
+
-


-
-
+
+
-
-
+









-

-
-
-
-
-
-
+
+
+
+
+
+

-
+
-
-
+


-
+


-
-
-
+
-
-
+
-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-

-
+
-
-
-

-
-
+
-
-
-
+
-
-
-





-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
-
-
-
-
-
-
+
-
-
+
-
-
-

-
-
-
-
+

-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-





-
+





-
-
-
-
-

+
-
+


-
-
-
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
-
+
+
+
+
-
-
+







-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
+
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
+
+

+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
-
-
-
-
-
+
-
-

-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+

-

-
+





-
-
-
-
-
-
-
-
-
-
+








-
-
-
-
-
-
+
+
+
+
+
+
+
+

+
-
-
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+







+
-
+
-
-
+


+
-
-
+
+
-
+

+
+
+

+
+
+

+
-
+
-
-
+

-
+

-

-
-
+
+
-

-
+


-
+
-
-
-
+


-
-
+
+




-
+
-

+
-
+
-

-
-
-
+
+
+

-
+


-
-
-
+
-


-
-
+
+
+




-
-
-
-
-
-
-
-
+
+
+


-
+




+
+
+
+




+
+


-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+



-
-
-
-
-
+
+
+
+
+

-
-





+
+
-
-
+
+
+

-
+
-













-
+

+
-
+
-
-
-
-
-



-
-
-
+
+
+
-
-
-
-
-
-

-
-
-

-
+
-
-


-
-
-
-
-
-
+
+
+
+
+
+
+
+


-










-
+

-
+
-
-


-
-
+
-
-
-
-
+

+



-
-
+
+


-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
-
-
+
+
-
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-

+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
-
-
+
-
-
-
-
-
-
+
+
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+


-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
-
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+

-
-
-
-
-
-
-
-
+
+



-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
-
-
-
-
+
+
+
+
+
+
+


-
+
-
-
-
-
-
+
+
+
-
-
-
-
-
-
+
+
-
-
-
+


-
+

+
-
-
-
+
+
+
+
+

-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
+
+
-
-
+
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+

-
-
-
-
-
-
+
+


-
+


-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
-

-
+
+

+

-
+

+

-
-
-




















-
+
-
-
-
-










ac_config_files="$ac_config_files Makefile tkConfig.sh wish.exe.manifest"
                              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.
# 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.
(
  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 \.
    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 \
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
      ;;
    esac |
    esac;
    sort
) |
} |
  sed '
     /^ac_cv_env_/b end
     t clear
     :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
     /^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"
      { $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
    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;}
    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 branch to the quote section.  Otherwise,
# take arguments), then we branch to the quote section.  Otherwise,
# look for a macro that doesn't take arguments.
ac_script='
cat >confdef2opt.sed <<\_ACEOF
:mline
/\\$/{
 N
 s,\\\n,,
 b mline
}
t clear
:clear
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
: clear
s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\),-D\1=\2,g
t quote
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\),-D\1=\2,g
t quote
b any
:quote
s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
s/\[/\\&/g
s/\]/\\&/g
s/\$/$$/g
d
: quote
s,[	 `~#$^&*(){}\\|;'"<>?],\\&,g
s,\[,\\&,g
s,\],\\&,g
s,\$,$$,g
H
:any
${
	g
	s/^\n//
	s/\n/ /g
	p
p
}
'
DEFS=`sed -n "$ac_script" confdefs.h`
_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=
U=
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" |
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
	 sed '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
  # 2. Add them.
  #    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'
  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}"
: ${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;}
{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
echo "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
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}
export SHELL
_ASEOF
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF
## --------------------- ##
## M4sh Initialization.  ##
## --------------------- ##

# Be more Bourne compatible
# Be Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
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
  # Zsh 3.x and 4.x performs 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 #(
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
  *posix*) :
    set -o posix ;; #(
  set -o posix
  *) :
     ;;
esac
fi

DUALCASE=1; export DUALCASE # for MKS sh

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


# Support unset when possible.
if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
# 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"

  as_unset=unset
# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
else
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

  as_unset=false
     ;;
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"
# Work around bugs in pre-3.0 UWIN ksh.
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
$as_unset 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

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
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH


  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
    eval $as_var=C; export $as_var
# 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 ()
  else
{
  as_status=$1; test $as_status -eq 0 && as_status=1
    $as_unset $as_var
  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

done

# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1
} # as_fn_set_status

# Required to use basename.
# 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 &&
if expr a : '\(a\)' >/dev/null 2>&1; then
   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
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

# Name of the executable.
as_me=`$as_basename -- "$0" ||
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	 X"$0" : 'X\(/\)$' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  /^X\/\(\/\).*/{
	    s//\1/
	    q
	  }
  	  /^X\/\(\/\).*/{ s//\1/; q; }
  	  s/.*/./; 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

ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  echo "#! /bin/sh" >conf$$.sh
-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  "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

       ;;
*)
  ECHO_N='-n';;
esac

  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.
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  if test "x$as_myself" = x; then
  rm -f conf$$.dir/conf$$.file
else
    as_myself=$0
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
  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 ||
  if test ! -f "$as_myself"; then
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
    { { 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
else
  as_ln_s='cp -pR'
fi
	 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;;
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null


# as_fn_mkdir_p
	 esac
       done
done
# -------------
# 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 #(

  # 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.
      *\'*) 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" ||
  # (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_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" |
    ' >$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
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
  # 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

	  }
	  /^X\(\/\/\)$/{
	    s//\1/
if expr a : '\(a\)' >/dev/null 2>&1; then
  as_expr=expr
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
else
  as_expr=false
fi

	  }
	  s/.*/./; q'`
      test -d "$as_dir" && break
    done
    test -z "$as_dirs" || eval "mkdir $as_dirs"
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'
  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"

fi
rm -f conf$$ conf$$.exe conf$$.file

} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
  as_mkdir_p='mkdir -p "$as_dir"'
  as_mkdir_p=:
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
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'"


exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" 	$as_nl"

# CDPATH.
$as_unset CDPATH

exec 6>&1
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to

# 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.
ac_log="
This file was extended by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was
# 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.6, 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
on `(hostname || uname -n) 2>/dev/null | sed 1q`
echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
"

echo >&5
_ACEOF

# Files that config.status was made for.
case $ac_config_files in *"
"*) set x $ac_config_files; shift; ac_config_files=$*;;
if test -n "$ac_config_files"; then
  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
esac
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
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
# Files that config.status was made for.
config_files="$ac_config_files"
fi

_ACEOF
cat >>$CONFIG_STATUS <<\_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
\`$as_me' instantiates files from templates according to the
current configuration.
and actions are specified as TAGs, all are instantiated by default.

Usage: $0 [OPTION]... [TAG]...
Usage: $0 [OPTIONS] [FILE]...

  -h, --help       print this help, then exit
  -V, --version    print version number and configuration settings, then exit
  -V, --version    print version number, then exit
      --config     print configuration, then exit
  -q, --quiet, --silent
                   do not print progress messages
  -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
  --file=FILE[:TEMPLATE]
		   instantiate the configuration file FILE

Configuration files:
$config_files

Report bugs to the package provider."
Report bugs to <bug-autoconf@gnu.org>."

_ACEOF

cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
cat >>$CONFIG_STATUS <<_ACEOF
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\\"
tk config.status 8.6
configured by $0, generated by GNU Autoconf 2.59,
  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"

Copyright (C) 2012 Free Software Foundation, Inc.
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."

ac_pwd='$ac_pwd'
srcdir='$srcdir'
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.
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=`expr "X$1" : 'X\([^=]*\)='`
    ac_optarg=
  --*=*)
    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 | --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 )
  --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
    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'"
    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;;
  --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.
  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
Try \`$0 --help' for more information." >&5
  -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
echo "$as_me: error: unrecognized option: $1
Try \`$0 --help' for more information." >&2;}
   { (exit 1); exit 1; }; } ;;

  *) as_fn_append ac_config_targets " $1"
  *) ac_config_targets="$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
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
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  exec $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
cat >>$CONFIG_STATUS <<\_ACEOF

# 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;;
  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 against having it here, and in addition,
# simply because there is no reason to put it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Create a temporary directory, and 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=$?
  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
  : "${ac_tmp:=$tmp}"
  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
  trap 'as_fn_exit 1' 1 2 13 15
  trap '{ (exit 1); 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=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
  test -n "$tmp" && test -d "$tmp"
}  ||
{
  tmp=./conf$$-$RANDOM
  (umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
  tmp=./confstat$$-$RANDOM
  (umask 077 && mkdir $tmp)
} ||
{
   echo "$me: cannot create a temporary directory in ." >&2
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

   { (exit 1); exit 1; }
}

_ACEOF

cat >>$CONFIG_STATUS <<_ACEOF

#
# CONFIG_FILES section.
#

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
# No need to generate the scripts if there are no CONFIG_FILES.
# This happens for instance when ./config.status config.h
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
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
fi

echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF


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
{
  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 '^'`
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
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
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
    break
  elif $ac_last_try; then
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
    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
  else
    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
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
  fi
done
rm -f conf$$subs.sh

cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
_ACEOF
sed -n '
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
h
s/^/S["/; s/!.*/"]=/
s,@TCL_DEFS@,$TCL_DEFS,;t t
s,@CYGPATH@,$CYGPATH,;t t
p
g
s/^[^!]*!//
s,@CELIB_DIR@,$CELIB_DIR,;t t
s,@DL_LIBS@,$DL_LIBS,;t t
s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t
:repl
t repl
s/'"$ac_delim"'$//
t delim
s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
s,@CFLAGS_NOLTO@,$CFLAGS_NOLTO,;t t
s,@MAN2TCLFLAGS@,$MAN2TCLFLAGS,;t t
:nl
h
s/\(.\{148\}\)..*/\1/
t more1
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/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
p
n
b repl
s,@TCLSH_PROG@,$TCLSH_PROG,;t t
s,@TK_WIN_VERSION@,$TK_WIN_VERSION,;t t
s,@MACHINE@,$MACHINE,;t t
:more1
s/["\\]/\\&/g; s/^/"/; s/$/"\\/
s,@TK_VERSION@,$TK_VERSION,;t t
s,@TK_MAJOR_VERSION@,$TK_MAJOR_VERSION,;t t
p
g
s/.\{148\}//
t nl
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
:delim
h
s/\(.\{148\}\)..*/\1/
t more2
s/["\\]/\\&/g; s/^/"/; s/$/"/
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
p
b
:more2
s/["\\]/\\&/g; s/^/"/; s/$/"\\/
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
p
g
s/.\{148\}//
t delim
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,@EXTRA_CFLAGS@,$EXTRA_CFLAGS,;t t
s,@DEPARG@,$DEPARG,;t t
' <conf$$subs.awk | sed '
/^[^""]/{
  N
  s/\n//
s,@CC_OBJNAME@,$CC_OBJNAME,;t t
}
' >>$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 &&
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,@TK_RES@,$TK_RES,;t t
  for (key in S) S_is_set[key] = 1
  FS = ""

s,@STLIB_LD@,$STLIB_LD,;t t
}
{
  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
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,@TK_SHARED_BUILD@,$TK_SHARED_BUILD,;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
  }

  print line
}
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,@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,@RES@,$RES,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF


_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 >>$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
  cat
fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF

    fi
# 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[	 ]*=[	 ]*/{
    if test ! -s $tmp/subs.frag; then
      ac_more_lines=false
h
s///
s/^/:/
    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
s/[	 ]*$/:/
s/:\$(srcdir):/:/g
s/:\${srcdir}:/:/g
s/:@srcdir@:/:/g
s/^:*//
  /@[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
s/:*$//
x
s/\(=[	 ]*\).*/\1/
G
s/\n//
s/^[^=]*=[	 ]*$//
}'
fi

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
	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"


eval set X "  :F $CONFIG_FILES      "
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
shift
for ac_tag
for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
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
  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
  case $ac_file in
  :L) ac_source=$1;;
  :[FH])
    ac_file_inputs=
  - | *:- | *:-:* ) # input from stdin
    for ac_f
    do
      case $ac_f in
      -) ac_f="$ac_tmp/stdin";;
	cat >$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'"
	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
    done

	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
    # 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'
  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
  * )   ac_file_in=$ac_file.in ;;
      { $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
  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" ||
  # 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 ||
$as_echo X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	 X"$ac_file" : 'X\(/\)' \| \
	 .     : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
  	  /^X\(\/\/\)$/{ s//\1/; q; }
  	  /^X\(\/\).*/{ s//\1/; q; }
  	  s/.*/./; q'`
	  }
	  /^X\(\/\/\)$/{
	    s//\1/
  { 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; }
	    q
	  }
	  /^X\(\/\).*/{
  	  /^X\(\/\).*/{ s//\1/; q; }
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
  as_dir="$ac_dir"; as_fn_mkdir_p
  	  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=.

case "$ac_dir" in
if test "$ac_dir" != .; then
.) 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|/||'`
  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'`
  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
else
  ac_dir_suffix= ac_top_builddir=
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
fi

case $srcdir in
  .)  # We are building in place.
  .)  # No --srcdir option.  We are building in place.
    ac_srcdir=.
    if test -z "$ac_top_builddir"; then
    ac_top_srcdir=$ac_top_builddir_sub
    ac_abs_top_srcdir=$ac_pwd ;;
  [\\/]* | ?:[\\/]* )  # Absolute name.
       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
    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 ;;
  *) # 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
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix



  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 $ac_mode in
  :F)
      case $f in
      -) echo $tmp/stdin ;;
  #
  # CONFIG_FILE
      [\\/$]*)
	 # Absolute (can't be DOS-style, as IFS=:)
  #

	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
_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=
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"
ac_sed_dataroot='
/datarootdir/ {
	 elif test -f "$srcdir/$f"; then
  p
  q
}
/@datadir@/p
/@docdir@/p
	   # Source tree
	   echo "$srcdir/$f"
/@infodir@/p
/@localedir@/p
	 else
/@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;}
	   # /dev/null tree
	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&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
   { (exit 1); exit 1; }; }
	 fi;;
      esac
    done` || { (exit 1); exit 1; }
_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
cat >>$CONFIG_STATUS <<_ACEOF
  sed "$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
cat >>$CONFIG_STATUS <<\_ACEOF
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s|@configure_input@|$ac_sed_conf_input|;t t
s,@configure_input@,$configure_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
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
$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

s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
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
" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
  rm -f $tmp/stdin
  if test x"$ac_file" != x-; then
  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
  esac \
    mv $tmp/out $ac_file
  else
  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 ;;



    cat $tmp/out
    rm -f $tmp/out
  fi
  esac

done # for ac_tag
done
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF

as_fn_exit 0
{ (exit 0); exit 0; }
_ACEOF
chmod +x $CONFIG_STATUS
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
  $ac_cs_success || { (exit 1); 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


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
337
338
339
340
341
342
343
344
345
346
347
348
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#! /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.6])
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.6
TK_MAJOR_VERSION=8
TK_MINOR_VERSION=6
TK_PATCH_LEVEL=".16"
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

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 ${TK_VERSION}.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}.])
fi
if test "${TCL_MINOR_VERSION}" -lt "${TK_MINOR_VERSION}"; then
    AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Tk ${TK_VERSION}${TK_PATCH_LEVEL} needs Tcl ${TK_VERSION}.
Use --with-tcl= option to indicate location of tclConfig.sh file for Tcl ${TK_VERSION}.])
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_LINK_IFELSE([AC_LANG_PROGRAM([[#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>])
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

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}"

eval "TK_SRC_DIR=\"`cd $srcdir/..; $CYGPATH $(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}"
eval "TK_BUILD_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TK_LIB_FLAG}\""

eval "TK_STUB_LIB_FLAG=\"-ltkstub${VER}${LIBFLAGSUFFIX}\""
eval "TK_BUILD_STUB_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TK_STUB_LIB_FLAG}\""

TK_STUB_LIB_SPEC="-L${libdir} ${TK_STUB_LIB_FLAG}"
TK_STUB_LIB_PATH="${libdir}/${TK_STUB_LIB_FILE}"
eval "TK_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(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}

#--------------------------------------------------------------------
# Adjust the defines for how the resources are built depending
# on symbols and static vs. shared.
#--------------------------------------------------------------------

if test ${SHARED_BUILD} = 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(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_CONFIG_FILES([Makefile tkConfig.sh wish.exe.manifest])
AC_OUTPUT

dnl Local Variables:
dnl mode: autoconf
dnl End:
Added win/gitmanifest.in.

1
+
git-
Changes to win/makefile.vc.
13
14
15
16
17
18
19
20
21


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

35
36
37
38
39
40
41
13
14
15
16
17
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) 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
# For MACRODEF, see TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md)
# or examine Sections 7-9 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.
#	tktest   -- Just builds the test shell.
#	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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
80
81
82
83
84
85
86


87
88
89
90
91
92
93







-
-







# 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)
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145


146
147
148
149
150
151
152
111
112
113
114
115
116
117







118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144







-
-
-
-
-
-
-


-
+















-
+
+







!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"
TKTEST		= "$(OUT_DIR)\$(PROJECT)test$(VERSION)$(SUFX).exe"
CAT32		= "$(OUT_DIR)\cat32.exe"

WISHOBJS = \
	$(TMP_DIR)\winMain.obj \
!if $(TCL_USE_STATIC_PACKAGES)
	$(TCLDDELIB) \
	$(TCLREGLIB) \
!endif
	$(TMP_DIR)\wish.res

TKTESTOBJS = \
	$(TMP_DIR)\testMain.obj \
	$(TMP_DIR)\tkSquare.obj \
	$(TMP_DIR)\tkTest.obj \
	$(TMP_DIR)\tkOldTest.obj \
	$(TMP_DIR)\tkWinTest.obj
	$(TMP_DIR)\tkWinTest.obj \
	$(TMP_DIR)\tktest.res

XLIBOBJS = \
	$(TMP_DIR)\xcolors.obj \
	$(TMP_DIR)\xdraw.obj \
	$(TMP_DIR)\xgc.obj \
	$(TMP_DIR)\ximage.obj \
	$(TMP_DIR)\xutil.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
205
206
207
208
209
210
211

212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237







-



-
















-







	$(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 \
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
300
301
302
303
304
305
306

307
308

309
310
311
312
313
314



315
316
317
318
319
320
321







-
+

-






-
-
-







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_STDLIB_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


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
450
451
452
453
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







-
+













+







$(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
	$(CONEXECMD) -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
	$(TCLSH) $(_TCLDIR)\tools\genStubs.tcl $(GENERICDIR)\ttk $(GENERICDIR)\ttk\ttk.decls
!endif


#---------------------------------------------------------------------
# Build the Windows HTML help file.
#---------------------------------------------------------------------

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
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







+
+
+
+
+
+
+



















+
+
+







#---------------------------------------------------------------------

$(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$@ $?

$(ROOT)\manifest.uuid:
   copy $(WIN_DIR)\gitmanifest.in $(ROOT)\manifest.uuid
   git rev-parse HEAD >>$(ROOT)\manifest.uuid

$(TMP_DIR)\tkUuid.h:	$(ROOT)\manifest.uuid
	copy $(WIN_DIR)\tkUuid.h.in+$(ROOT)\manifest.uuid $(TMP_DIR)\tkUuid.h

$(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$@ $?

$(TMP_DIR)\tkWindow.obj: $(GENERICDIR)\tkWindow.c $(TMP_DIR)\tkUuid.h
	$(cc32) $(pkgcflags) -I$(TMP_DIR) -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$@ $?
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
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







+




















-
+


-
+

-
+







{$(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
$(TMP_DIR)\tktest.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 {![package vsatisfies [package provide Tcl] 8.6.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$(DOTVERSION).dll] Tk]
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(DOTVERSION).dll]]
} else {
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)] Tk]
    package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin $(TKLIBNAME)]]
}
<<
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)\"
!endif

#"

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.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17

18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16

17



18
19

20
21

22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100






-
-
+
+








-
+
-
-
-


-
+

-











-
+







-
+
















-
-
+
+













-
+



















-
+







/*
 * ----------------------------------------------------------------------------
 * nmakehlp.c --
 *
 *	This is used to fix limitations within nmake and the environment.
 *
 * Copyright (c) 2002 by David Gravereaux.
 * Copyright (c) 2006 by Pat Thoyts
 * Copyright (c) 2002 David Gravereaux.
 * Copyright (c) 2006 Pat Thoyts
 *
 * 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
#ifdef _MSC_VER
#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")
#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)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif

/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1900
#define   snprintf	_snprintf
#endif


/* protos */

static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(const char **options, int count);
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, '\0'};
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
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;
    char *s;
    const char *s;

    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);

    /*
     * Make sure the compiler and linker aren't effected by the outside world.
     */

    SetEnvironmentVariable("CL", "");
    SetEnvironmentVariable("LINK", "");

    if (argc > 1 && *argv[1] == '-') {
	switch (*(argv[1]+1)) {
	case 'c':
	    if (argc != 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
		        "usage: %s -c <compiler option>\n"
			"usage: %s -c <compiler option>\n"
			"Tests for whether cl.exe supports an option\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForCompilerFeature(argv[2]);
206
207
208
209
210
211
212
213
214


215
216
217
218
219

220
221
222
223
224
225

226
227
228
229
230
231

232
233
234
235
236
237
238
202
203
204
205
206
207
208


209
210
211
212
213
214

215
216
217
218
219
220

221
222
223
224
225
226

227
228
229
230
231
232
233
234







-
-
+
+




-
+





-
+





-
+







    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    char cmdline[100];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = FALSE;

    /*
     * Create a non-inheritible pipe.
     * Create a non-inheritable pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     * Dupe the write side, make it inheritable, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284







-
+








    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],
		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.
318
319
320
321
322
323
324
325
326
327
328
329





330
331
332
333
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350


351
352
353
354
355

356
357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
314
315
316
317
318
319
320





321
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344


345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370







-
-
-
-
-
+
+
+
+
+




-
+














-
-
+
+




-
+











-
+








    /*
     * Look for the commandline warning code in both streams.
     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
     */

    return !(strstr(Out.buffer, "D4002") != NULL
             || strstr(Err.buffer, "D4002") != NULL
             || strstr(Out.buffer, "D9002") != NULL
             || strstr(Err.buffer, "D9002") != NULL
             || strstr(Out.buffer, "D2021") != NULL
             || strstr(Err.buffer, "D2021") != NULL);
	    || strstr(Err.buffer, "D4002") != NULL
	    || strstr(Out.buffer, "D9002") != NULL
	    || strstr(Err.buffer, "D9002") != NULL
	    || strstr(Out.buffer, "D2021") != NULL
	    || strstr(Err.buffer, "D2021") != NULL);
}

static int
CheckForLinkerFeature(
    const char **options,
    char **options,
    int count)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    int i;
    char cmdline[255];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     * Dupe the write side, make it inheritable, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418







-
+








    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],
		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
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







-









-
+









-
+








-
-
+
+



-
-
-
+
+








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) {
	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(*p)) {
		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))) {
		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;
		*q = 0;
		szResult = p;
		break;
	    }
	}
	fclose(fp);
    }
    return szResult;
}
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571







-
+







    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));
    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;
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
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







-
+







-
-
-
+
+
+







-

-







-
+




-
+
















-
+













-
+
















-
+








+
+
+
+
+
+
+
+
+
+
+













-
+
-
-
-
+
-
-
-
















+
-
+


-
+

+

-
+

+














-
+

+









-
+

+

-
+

+



-
+















-
-
+
+

-
-
-
-
+
+
+
+



+
-
-
+
+



-
+

+







    }
}

/*
 * SubstituteFile --
 *	As windows doesn't provide anything useful like sed and it's unreliable
 *	to use the tclsh you are building against (consider x-platform builds -
 *	eg compiling AMD64 target from IX86) we provide a simple substitution
 *	e.g. compiling AMD64 target from IX86) we provide a simple substitution
 *	option here to handle autoconf style substitutions.
 *	The substitution file is whitespace and line delimited. The file should
 *	consist of lines matching the regular expression:
 *	  \s*\S+\s+\S*$
 *
 *	Usage is something like:
 *	  nmakehlp -S << $** > $@
 *        @PACKAGE_NAME@ $(PACKAGE_NAME)
 *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
 *        <<
 *	    @PACKAGE_NAME@ $(PACKAGE_NAME)
 *	    @PACKAGE_VERSION@ $(PACKAGE_VERSION)
 *	    <<
 */

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
	 * Build a list of substitutions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, 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 */
#ifdef _DEBUG
#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, cbBuffer, fp) != NULL) {
	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(szBuffer);
	    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];
    char szTmp[MAX_PATH + 1];

    char *p;
    GetCurrentDirectory(MAX_PATH, szCwd);
    while ((p = strchr(szPath, '/')) && *p)
    GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
	*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];
    size_t dirlen;
    int dirlen, keylen, ret;
    int keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL)
    if (dir == NULL || keypath == NULL) {
	return 2; /* Have no real error reporting mechanism into nmake */
    }
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path))
    if ((dirlen + 3) > sizeof(path)) {
	return 2;
    }
    strncpy(path, dir, dirlen);
    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
    keylen = strlen(keypath);

#if 0 /* This function is not available in Visual C++ 6 */
    /*
     * Use numerics 0 -> FindExInfoStandard,
     * 1 -> FindExSearchLimitToDirectories,
     * as these are not defined in Visual C++ 6
     */
    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
    hSearch = FindFirstFile(path, &finfo);
#endif
    if (hSearch == INVALID_HANDLE_VALUE)
    if (hSearch == INVALID_HANDLE_VALUE) {
	return 1; /* Not found */
    }

    /* Loop through all subdirs checking if the keypath is under there */
    ret = 1; /* Assume not found */
    do {
	int sublen;
	/*
	 * We need to check it is a directory despite the
	 * FindExSearchLimitToDirectories in the above call. See SDK docs
	 */
	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
	    continue;
	}
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	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)) {
	if (FileExists(path)) {
	    /* Found a match, print to stdout */
	    path[dirlen+1+sublen] = '\0';
	    QualifyPath(path);
	    ret = 0;
	    break;
	}
    } while (FindNextFile(hSearch, &finfo));
    FindClose(hSearch);
    return ret;
}

/*
 * LocateDependency --
 *
 *	Locates a dependency for a package.
 *        keypath - a relative path within the package directory
 *          that is used to confirm it is the correct directory.
 *	    keypath - a relative path within the package directory
 *	      that is used to confirm it is the correct directory.
 *	The search path for the package directory is currently only
 *      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.
 *	    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 i, ret;
    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
    int ret;
    static const char *paths[] = {"..", "..\\..", "..\\..\\.."};

    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	if (ret == 0) {
	    return ret;
	}
    }
    return ret;
}


/*
 * Local variables:
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
1
2
3
4
5
6
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_DEBUG
#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
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
38
39
40
41
42
43
44

45

46
47
48
49
50
51
52
53







-

-
+







BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tk DLL\0"
            VALUE "OriginalFilename", "tk" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".dll\0"
            VALUE "CompanyName", "ActiveState Corporation\0"
            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 2001 by ActiveState Corporation, et al\0"
            VALUE "LegalCopyright", "Copyright \251 1987-2022 Regents of the University of California and other parties\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
Added win/rc/tktest.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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
//
// 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
 FILEFLAGS	VS_FF_DEBUG
#else
 FILEFLAGS	0x0L
#endif
 FILEOS		VOS__WINDOWS32
 FILETYPE	VFT_APP
 FILESUBTYPE	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tktest Application\0"
            VALUE "OriginalFilename", "tktest" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".exe\0"
            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 1987-2022 Regents of the University of California and other parties\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

//
// Icon
//
//   The icon whose name or resource ID is lexigraphically first, is used
//   as the application's icon.
//

app                      ICON    DISCARDABLE     "wish.ico"

#if STATIC_BUILD
#include "tk_base.rc"
#endif

//
// This enables themed scrollbars in XP by trying to use comctl32 v6.
//

#ifndef RT_MANIFEST
#define RT_MANIFEST     24
#endif
#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#endif
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "wish.exe.manifest"
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
1
2
3
4
5
6
7
8
9
10
11
12
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_STATIC SUFFIX_DEBUG
#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
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
44
45
46
47
48
49
50

51

52
53
54
55
56
57
58
59







-

-
+







BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Wish Application\0"
            VALUE "OriginalFilename", "wish" STRINGIFY(TK_MAJOR_VERSION) STRINGIFY(TK_MINOR_VERSION) SUFFIX ".exe\0"
            VALUE "CompanyName", "ActiveState Corporation\0"
            VALUE "FileVersion", TK_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 2000 by ActiveState Corporation, et al\0"
            VALUE "LegalCopyright", "Copyright \251 1987-2022 Regents of the University of California and other parties\0"
            VALUE "ProductName", "Tk " TK_VERSION " for Windows\0"
            VALUE "ProductVersion", TK_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
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
Changes to win/rules-ext.vc.
27
28
29
30
31
32
33

34





35
36
37
38
39
40
41
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46







+
-
+
+
+
+
+







!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 "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
!endif
!else
!if [copy x86_64-w64-mingw32-nmakehlp.exe nmakehlp.exe >NUL]
!endif
!endif

# First locate the Tcl directory that we are working with.
!if "$(TCLDIR)" != ""

_RULESDIR = $(TCLDIR:/=\)

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
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34








-
+

















-
+







#------------------------------------------------------------- -*- 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
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/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
RULES_VERSION_MINOR = 10

# 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)" == ""
75
76
77
78
79
80
81


82
83
84



85
86
87
88
89
90
91
92
75
76
77
78
79
80
81
82
83



84
85
86

87
88
89
90
91
92
93







+
+
-
-
-
+
+
+
-







# 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. Extract Tcl, Tk, and possibly extensions, version numbers from the
#    headers
# 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
# 7. Parse the OPTS macro value for user-specified build configuration
# 8. Parse the STATS macro value for statistics instrumentation
# 9. 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.
407
408
409
410
411
412
413
414
415


416
417
418
419
420
421
422
408
409
410
411
412
413
414


415
416
417
418
419
420
421
422
423







-
-
+
+







# 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
# ARCH - set to IX86, ARM64 or AMD64 depending on 32- or 64-bit target
# NATIVE_ARCH - set to IX86, ARM64 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.
431
432
433
434
435
436
437


438
439
440
441
442
443
444
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447







+
+







_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)elif defined(_M_ARM64) >> vercl.x] \
    && ![echo ARCH=ARM64 >> 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
455
456
457
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
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







+
+
+
















+
+















+
+








#----------------------------------------------------------------
# The MACHINE macro is used by legacy makefiles so set it as well
!ifdef MACHINE
!if "$(MACHINE)" == "x86"
!undef MACHINE
MACHINE = IX86
!elseif "$(MACHINE)" == "arm64"
!undef MACHINE
MACHINE = ARM64
!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
!elseif "$(MACHINE)" == "ARM64"
PLATFORM_IDENTIFY = win32-arm
!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
!elseif ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i ARM | findstr /i 64-bit]
NATIVE_ARCH=ARM64
!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
537
538
539
540
541
542
543

544
545




546
547
548
549
550
551
552
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567







+


+
+
+
+







!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 "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif
!else
!if [copy $(NMAKEHLPC:nmakehlp.c=x86_64-w64-mingw32-nmakehlp.exe) nmakehlp.exe >NUL]
!endif
!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:
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+













+

-
-
+
+









-
-







# 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. Extract various version numbers from headers
# 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_RELEASE_SERIAL
# TCL_PATCH_LEVEL
# TCL_PATCH_LETTER
# TCL_VERSION
# TK_MAJOR_VERSION
# TK_MINOR_VERSION
# TK_RELEASE_SERIAL
# TK_PATCH_LEVEL
# TK_PATCH_LETTER
# 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)" "define 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_RELEASE_SERIAL = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_RELEASE_SERIAL >> 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) "define 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_RELEASE_SERIAL = \>> versions.vc] \
   && [nmakehlp -V "$(_TK_H)" TK_RELEASE_SERIAL >> 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 [nmakehlp -f $(TCL_PATCH_LEVEL) "a"]
TCL_PATCH_LETTER = a
!elseif [nmakehlp -f $(TCL_PATCH_LEVEL) "b"]
TCL_PATCH_LETTER = b
!else
TCL_PATCH_LETTER = .
!endif

!if defined(_TK_H)

TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
!if [nmakehlp -f $(TK_PATCH_LEVEL) "a"]
TK_PATCH_LETTER = a
!elseif [nmakehlp -f $(TK_PATCH_LEVEL) "b"]
TK_PATCH_LETTER = b
!else
TK_PATCH_LETTER = .
!endif

!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

########################################################################
# 6. Parse the OPTS macro to work out the requested build configuration.
# 7. 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)
#           Default: 1 for Tcl 8.7 and up, 0 otherwise.
# 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.
#           in the Tcl and Wish shell. 0 -> keep them as shared libraries. Does
#           not impact shared Tcl builds. Implied by STATIC_BUILD since Tcl 8.7.
# 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
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
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







-
+
















-
+




-
-
-
-
-







!if [nmakehlp -f $(OPTS) "nomsvcrt"]
!message *** Doing nomsvcrt
MSVCRT		= 0
!else
!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
!else
!if $(STATIC_BUILD)
!if $(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) < 7 && $(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 $(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
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
963
964
965
966
967
968
969

970
971
972
973
974
975
976
977







-
+







MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!endif

################################################################
# 7. Parse the STATS macro to configure code instrumentation
# 8. 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
862
863
864
865
866
867
868
869

870
871
872
873
874
875
876
993
994
995
996
997
998
999

1000
1001
1002
1003
1004
1005
1006
1007







-
+







!else
TCL_COMPILE_DEBUG   = 0
!endif

!endif

####################################################################
# 8. Parse the CHECKS macro to configure additional compiler checks
# 9. 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
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
1025
1026
1027
1028
1029
1030
1031





























































































1032
1033
1034
1035
1036
1037
1038







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







!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.,
#
1083
1084
1085
1086
1087
1088
1089

1090

1091




1092

1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
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







+

+
-
+
+
+
+

+





+







!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)

# TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc
TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip
TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip

!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)
TCLSCRIPTZIP    = $(OUT_DIR)\$(TCLSCRIPTZIPNAME)

TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
TCL_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"

!else # !$(DOING_TCL)

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
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







+



















+







# "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
TCLSCRIPTZIP	= $(_TCLDIR)\lib\$(TCLSCRIPTZIPNAME)
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
TCLSCRIPTZIP	= $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCLSCRIPTZIPNAME)
TCLTOOLSDIR	= $(_TCLDIR)\tools
TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"

!endif # TCLINSTALL

tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"

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
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







-
-
+
+
+
+

+
+
+
+
+






-
+
+














+
+

+










+
+

+







-
+
+
+
+
+
+
+







!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
TKLIBNAME8	= tk$(TK_VERSION)$(SUFX).$(EXT)
TKLIBNAME9	= tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
!if $(TCL_MAJOR_VERSION) == 8
TKLIBNAME	= tk$(TK_VERSION)$(SUFX).$(EXT)
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib
!else
TKLIBNAME	= tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
TKIMPLIBNAME	= tcl9tk$(TK_VERSION)$(SUFX).lib
!endif
TKSTUBLIBNAME	= tkstub$(TK_VERSION).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)"
TK_INCLUDES     = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
TKSCRIPTZIP     = $(OUT_DIR)\$(TKSCRIPTZIPNAME)

!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"
TKSCRIPTZIP     = $(_TKDIR)\lib\$(TKSCRIPTZIPNAME)

!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"
TKSCRIPTZIP     = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSCRIPTZIPNAME)

!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)
PRJLIBNAME8	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIBNAME9	= tcl9$(PROJECT)$(VERSION)$(SUFX).$(EXT)
!if $(TCL_MAJOR_VERSION) == 8
PRJLIBNAME	= $(PRJLIBNAME8)
!else
PRJLIBNAME	= $(PRJLIBNAME9)
!endif
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.
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
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







-
+












-
-
+
+







# 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
# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration options
# 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	= /DSTDC_HEADERS /DUSE_NMAKE=1
!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
1307
1308
1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319
1320
1321
1374
1375
1376
1377
1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
1388







-
+







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"
!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
OPTDEFINES	= $(OPTDEFINES) /DMP_64BIT
!endif
!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) /DTCL_NO_DEPRECATED
!endif

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
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







-
+






-
+



-
-
-







!if $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_OPTIMIZED
!endif
!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "AMD64"
!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
OPTDEFINES	= $(OPTDEFINES) /DTCL_CFG_DO64BIT
!endif
!if $(VCVERSION) < 1300
OPTDEFINES	= $(OPTDEFINES) /DNO_STRTOI64=1
!endif

!if "$(TCL_MAJOR_VERSION)" == "8"
!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
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
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







-
-
+
+

-
+














+
+
+
+
+







cdebug = $(OPTIMIZATIONS)
!if $(SYMBOLS)
cdebug = $(cdebug) -Zi
!endif

!endif # $(DEBUG)

# cwarn includes default warning levels.
cwarn = $(WARNINGS)
# cwarn includes default warning levels, also C4090 (buggy) and C4146 is useless.
cwarn = $(WARNINGS) -wd4090 -wd4146

!if "$(MACHINE)" == "AMD64"
!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
# 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

# cpuid is only available on intel machines
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "AMD64"
carch = $(carch) /DHAVE_CPUID=1
!endif

!if $(DEBUG)
# Turn warnings into errors
cwarn = $(cwarn) -WX
!endif

INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
1452
1453
1454
1455
1456
1457
1458
1459

1460
1461
1462
1463
1464
1465
1466
1521
1522
1523
1524
1525
1526
1527

1528
1529
1530
1531
1532
1533
1534
1535







-
+







# 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)
stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) /Zl /GL- /DSTATIC_BUILD $(INCLUDES) $(USE_STUBS_DEFS)

# Link flags

!if $(DEBUG)
ldebug	= -debug -debugtype:cv
!else
ldebug	= -release -opt:ref -opt:icf,3
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
1544
1545
1546
1547
1548
1549
1550












1551
1552
1553
1554
1555
1556
1557







-
-
-
-
-
-
-
-
-
-
-
-







!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.
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
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







-
+
















+

-
+
+
+
+
+


+

-
+
+
+
+
+








+
+








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) \
	    $(TCL_INCLUDES) /DSTATIC_BUILD=$(STATIC_BUILD) \
	    /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 if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
	    [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } >> $(OUT_DIR)\pkgIndex.tcl
!else
default-pkgindex:
	@echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
	    [list load [file join $$dir $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
	@echo } >> $(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)
@PKG_LIB_FILE8@      $(PRJLIBNAME8)
@PKG_LIB_FILE9@      $(PRJLIBNAME9)
<<

default-install: default-install-binaries default-install-libraries
!if $(SYMBOLS)
default-install: default-install-pdbs
!endif

1595
1596
1597
1598
1599
1600
1601


1602
1603
1604
1605
1606
1607
1608
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679







+
+







	@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)\"

# "emacs font-lock highlighting fix

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:
1760
1761
1762
1763
1764
1765
1766
1767
1768


1769
1770
1771
1772
1773
1774
1775
1831
1832
1833
1834
1835
1836
1837


1838
1839
1840
1841
1842
1843
1844
1845
1846







-
-
+
+







!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"
!if exist("$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake")
TCLNMAKECONFIG	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake"
!endif
!endif # TCLINSTALL

!if $(CONFIG_CHECK)
!ifdef TCLNMAKECONFIG
!include $(TCLNMAKECONFIG)

Changes to win/stubs.c.
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
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







-
+










-
+










-
+







    return 0;
}

int
XNoOp(
    Display *display)
{
    display->request++;
    LastKnownRequestProcessed(display)++;
    return 0;
}

XAfterFunction
XSynchronize(
    Display *display,
    Bool onoff)
{
    (void)onoff;

    display->request++;
    LastKnownRequestProcessed(display)++;
    return NULL;
}

int
XSync(
    Display *display,
    Bool discard)
{
    (void)discard;

    display->request++;
    LastKnownRequestProcessed(display)++;
    return 0;
}

VisualID
XVisualIDFromVisual(
    Visual *visual)
{
Added win/svnmanifest.in.

1
+
svn-r
Changes to win/targets.vc.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







#------------------------------------------------------------- -*- 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.
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for docs.

$(PROJECT): setup pkgindex $(PRJLIB)

!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
	$(LIBCMD) $**
Changes to win/tcl.m4.
24
25
26
27
28
29
30
31

32
33

34
35
36
37
38
39
40
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],
	    AS_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig="${withval}")
	    [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
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],
	    AS_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig="${withval}")
	    [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
262

263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280



281
282








283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
247
248
249
250
251
252
253

254
255
256
257
258
259
260

261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304







-







-
+


-
+












-
-
-
+
+
+


+
+
+
+
+
+
+
+








-







#
# 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
        AC_MSG_RESULT([loading])
	AC_MSG_RESULT([loading])
	. "${TCL_BIN_DIR}/tclConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
	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.
    #

    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}
	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_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)
316
317
318
319
320
321
322
323

324
325
326

327
328
329
330
331
332
333
322
323
324
325
326
327
328

329
330
331

332
333
334
335
336
337
338
339







-
+


-
+







#		TK_BIN_DIR
#------------------------------------------------------------------------

AC_DEFUN([SC_LOAD_TKCONFIG], [
    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])

    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
        AC_MSG_RESULT([loading])
	AC_MSG_RESULT([loading])
	. "${TK_BIN_DIR}/tkConfig.sh"
    else
        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
	AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
    fi


    AC_SUBST(TK_BIN_DIR)
    AC_SUBST(TK_SRC_DIR)
    AC_SUBST(TK_LIB_FILE)
])
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376



































377

378
379
380
381
382
383
384
360
361
362
363
364
365
366








367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
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 "${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
])

#------------------------------------------------------------------------
# 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: on)],
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "$tcl_ok" = "yes"; then
	AC_MSG_RESULT([yes (default)])
	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)
    fi
    AC_SUBST(SHARED_BUILD)
    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
430
431
432
433
434
435
436
437
438
439
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)

459
460
461
462
463
464
465

466
467
468
469
470
471
472
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509







+







# Results:
#
#	Can the following vars:
#		EXTRA_CFLAGS
#		CFLAGS_DEBUG
#		CFLAGS_OPTIMIZE
#		CFLAGS_WARNING
#		CFLAGS_NOLTO
#		LDFLAGS_DEBUG
#		LDFLAGS_OPTIMIZE
#		LDFLAGS_CONSOLE
#		LDFLAGS_WINDOW
#		CC_OBJNAME
#		CC_EXENAME
#		CYGPATH
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
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







+
+
+
+
+
+
+
+
+
+
+






-




-
+






-
+



-
-
-
+
+
+











+
+
+
+
+
+
+







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)
    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.
    # which requires x86|amd64|arm64|ia64.
    MACHINE="X86"

    if test "$GCC" = "yes"; then

      AC_CACHE_CHECK(for cross-compile version of gcc,
	ac_cv_cross,
	AC_TRY_COMPILE([
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
	    #ifndef _WIN32
		#error cross-compiler
	    #endif
	], [],
	ac_cv_cross=no,
	ac_cv_cross=yes)
	]], [[]])],
	[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"
	    ;;
	    arm64|aarch64)
		CC="aarch64-w64-mingw32-${CC}"
		LD="aarch64-w64-mingw32-ld"
		AR="aarch64-w64-mingw32-ar"
		RANLIB="aarch64-w64-mingw32-ranlib"
		RC="aarch64-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"
	    ;;
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
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







-
+

-
+









-
+



-
-
-
+
+
+




+
+
+




-
+


-
+
-
-
-
+
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	    CYGPATH=echo
	fi
	conftest=
	cyg_conftest=
    fi

    if test "$CYGPATH" = "echo"; then
        DEPARG='"$<"'
	DEPARG='"$<"'
    else
        DEPARG='"$(shell $(CYGPATH) $<)"'
	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"
	AC_CACHE_CHECK(for mingw32 version of gcc,
	    ac_cv_win32,
	    AC_TRY_COMPILE([
	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		#ifdef _WIN32
		    #error win32
		#endif
	    ], [],
	    ac_cv_win32=no,
	    ac_cv_win32=yes)
	    ]], [[]])],
	    [ac_cv_win32=no],
	    [ac_cv_win32=yes])
	)
	if test "$ac_cv_win32" != "yes"; then
	    AC_MSG_ERROR([${CC} cannot produce win32 executables.])
	fi
	if test "$do64bit" != "arm64"; then
	    extra_cflags="$extra_cflags -DHAVE_CPUID=1"
	fi

	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain"
	AC_CACHE_CHECK(for working -municode linker flag,
	    ac_cv_municode,
	AC_TRY_LINK([
	AC_LINK_IFELSE([AC_LANG_PROGRAM([[
	#include <windows.h>
	int APIENTRY wWinMain(HINSTANCE a, HINSTANCE b, LPWSTR c, int d) {return 0;}
	],
	]], [[]])],
	[],
	    ac_cv_municode=yes,
	    ac_cv_municode=no)
	    [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
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto"
	AC_CACHE_CHECK(for working -fno-lto,
	    ac_cv_nolto,
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
	    [ac_cv_nolto=yes],
	    [ac_cv_nolto=no])
	)
	CFLAGS=$hold_cflags
	if test "$ac_cv_nolto" = "yes" ; then
	    CFLAGS_NOLTO="-fno-lto"
	else
	    CFLAGS_NOLTO=""
	fi
    fi

    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--enable-auto-image-base"
    AC_CACHE_CHECK(for working --enable-auto-image-base,
	ac_cv_enable_auto_image_base,
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
	[ac_cv_enable_auto_image_base=yes],
	[ac_cv_enable_auto_image_base=no])
    )
    CFLAGS=$hold_cflags
    if test "$ac_cv_enable_auto_image_base" = "yes" ; then
	extra_ldflags="$extra_ldflags -Wl,--enable-auto-image-base"
    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"
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
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







-
+


-
+


-
+




-
+





-
+







-
+


-
-
-
+
+
+






-
+








-
+







	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])
	    AC_MSG_RESULT([using static flags])
	    runtime=
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])
	    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.])
		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"
	    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%.a,\[$]@)"
	    -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=".dll"
	LIBSUFFIX=".a"
	LIBFLAGSUFFIX=""
	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 -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith"
	CFLAGS_WARNING="-Wall -Wpointer-arith"
	LDFLAGS_DEBUG=
	LDFLAGS_OPTIMIZE=

	case "${CC}" in
	    *++)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wno-format"
		;;
	    *)
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wc++-compat -Wdeclaration-after-statement"
		CFLAGS_WARNING="${CFLAGS_WARNING} -Wdeclaration-after-statement"
		;;
	esac

	# Specify the CC output file names based on the target name
	CC_OBJNAME="-o \[$]@"
	CC_EXENAME="-o \[$]@"

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
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







+
+
+
+


-
+


-
+



-
-
-
+
+
+


-
-
-
+
+
+






-
+


-
+


-
+



-
+











-
-
-
+
+
+






+
+
+




















-
-
+
















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+







	LDFLAGS_WINDOW="-mwindows ${extra_ldflags}"

	case "$do64bit" in
	    amd64|x64|yes)
		MACHINE="AMD64" ; # assume AMD64 as default 64-bit build
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		;;
	    arm64|aarch64)
		MACHINE="ARM64"
		AC_MSG_RESULT([   Using ARM64 $MACHINE mode])
		;;
	    ia64)
		MACHINE="IA64"
		AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		AC_MSG_RESULT([   Using IA64 $MACHINE mode])
		;;
	    *)
		AC_TRY_COMPILE([
		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
		    #ifndef _WIN64
			#error 32-bit
		    #endif
		], [],
			tcl_win_64bit=yes,
			tcl_win_64bit=no
		]], [[]])],
			[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])
		    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])
	    AC_MSG_RESULT([using static flags])
	    runtime=-MT
	    LIBRARIES="\${STATIC_LIBRARIES}"
	    EXESUFFIX="s.exe"
	    EXESUFFIX="s\${DBGX}.exe"
	else
	    # dynamic
            AC_MSG_RESULT([using shared flags])
	    AC_MSG_RESULT([using shared flags])
	    runtime=-MD
	    # Add SHLIB_LD_LIBS to the Make rule, not here.
	    LIBRARIES="\${SHARED_LIBRARIES}"
	    EXESUFFIX=".exe"
	    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=".dll"
	LIBSUFFIX=".lib"
	LIBFLAGSUFFIX=""
	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
		    ;;
		arm64|aarch64)
		    MACHINE="ARM64"
		    ;;
		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"
		    ;;
		*)
		    ;;
	esac

	if test "$do64bit" != "no" ; then
	    RC="rc"
	    CFLAGS_DEBUG="-nologo -Zi -Od ${runtime}d"
	    # Do not use -O2 for Win64 - this has proved buggy in code gen.
	    CFLAGS_OPTIMIZE="-nologo -O1 ${runtime}"
	    CFLAGS_OPTIMIZE="-nologo -O2 ${runtime}"
	    lflags="${lflags} -nologo -MACHINE:${MACHINE}"
	    LINKBIN="link"
	    # Avoid 'unresolved external symbol __security_cookie' errors.
	    # c.f. http://support.microsoft.com/?id=894573
	    LIBS="$LIBS bufferoverflowU.lib"
	else
	    RC="rc"
	    # -Od - no optimization
	    # -WX - warnings as errors
	    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"
	    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
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
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







-
+















-
+














-
-
-
-
+
+
+
+














-
+



-
+

-
-
-
+
+
+












-
+




-
+



-
-
-
+
+
+






-
-






-
+
-


-
-
-
+
+
+












+




















-
-
+
+

-
+


-
+








	# 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
	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_TRY_RUN([
	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)
	]])],
	    [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([
	    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)
	    ]])],
		[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([
	    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)
	    ]])],
	    [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([],
	    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)
	    ]])],
	    [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

    # DL_LIBS is empty, but then we match the Unix version
    AC_SUBST(DL_LIBS)
    AC_SUBST(CFLAGS_DEBUG)
    AC_SUBST(CFLAGS_OPTIMIZE)
    AC_SUBST(CFLAGS_WARNING)
    AC_SUBST(CFLAGS_NOLTO)
])

#------------------------------------------------------------------------
# SC_WITH_TCL --
#
#	Location of the Tcl build directory.
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--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
    if test -d ../../tcl8.6$1/win;  then
	TCL_BIN_DEFAULT=../../tcl8.6$1/win
    else
	TCL_BIN_DEFAULT=../../tcl8.7/win
	TCL_BIN_DEFAULT=../../tcl8.6/win
    fi

    AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 8.7 binaries from DIR],
    AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl 8.6 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
1001
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191







-
+







#	extension can't assume that an executable Tcl shell exists at
#	build time.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#	Substitutes the following values:
#		TCLSH_PROG
#------------------------------------------------------------------------

AC_DEFUN([SC_PROG_TCLSH], [
    AC_MSG_CHECKING([for tclsh])

    AC_CACHE_VAL(ac_cv_path_tclsh, [
1047
1048
1049
1050
1051
1052
1053
1054

1055
1056
1057
1058
1059
1060

1061
1062
1063
1064
1065
1066
1067
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
1243







-
+





-
+







#	when running tests from an extension build directory. It is not
#	correct to use the TCLSH_PROG in cases like this.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#	Substitutes 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}
    BUILD_TCLSH=${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}\${EXESUFFIX}
    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
1280
1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291
1292
1293
1294







-
+







#		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],
	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
1313
1314
1315
1316
1317
1318
1319


































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
	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)
])
Changes to win/tkConfig.sh.in.
21
22
23
24
25
26
27
28
29
30


31
32
33
34
35
36
37
38

39
40
41
42

43
44
45
46

47
48
49
50
51
52
53
21
22
23
24
25
26
27



28
29
30
31
32
33
34
35
36

37
38
39
40

41
42
43
44

45
46
47
48
49
50
51
52







-
-
-
+
+







-
+



-
+



-
+








# -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=
# 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@'

# Top-level directory in which Tcl's platform-independent files are
# Top-level directory in which Tk's platform-independent files are
# installed.
TK_PREFIX='@prefix@'

# Top-level directory in which Tcl's platform-specific files (e.g.
# Top-level directory in which Tk's platform-specific files (e.g.
# executables) are installed.
TK_EXEC_PREFIX='@exec_prefix@'

# -l flag to pass to the linker to pick up the Tcl library
# -l flag to pass to the linker to pick up the Tk library
TK_LIB_FLAG='@TK_LIB_FLAG@'

# String to pass to linker to pick up the Tk library from its
# build directory.
TK_BUILD_LIB_SPEC='@TK_BUILD_LIB_SPEC@'

# String to pass to linker to pick up the Tk library from its
Added win/tkUuid.h.in.

1
+
#define TK_VERSION_UUID \
Changes to win/tkWin.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
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20

21

22
23
24

25
26
27

28



29
30
31
32
33
34
35






-
+













-
+
-



-
+


-
+
-
-
-







/*
 * tkWin.h --
 *
 *	Declarations of public types and interfaces that are only
 *	available under Windows.
 *
 * Copyright (c) 1996-1997 by Sun Microsystems, Inc.
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#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
 * WINVER = 0x0500 means Windows 2000 and above
 * support Windows XP, but the Vista-specifics are tested at runtime.
 */

#ifndef WINVER
#   define WINVER 0x0600
#define WINVER 0x0500
#endif
#ifndef _WIN32_WINNT
#   define _WIN32_WINNT 0x0600
#define _WIN32_WINNT 0x0500
#endif
#ifndef _WIN32_IE
#   define _WIN32_IE 0x0700
#endif

#ifndef _TK
#include <tk.h>
#endif

#define WIN32_LEAN_AND_MEAN
Changes to win/tkWin32Dll.c.
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126


127

128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
97
98
99
100
101
102
103

104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
+


-















-
+



+
+
-
+










-
+








BOOL APIENTRY
DllMain(
    HINSTANCE hInstance,
    DWORD reason,
    LPVOID reserved)
{
#ifdef HAVE_NO_SEH
#if defined(HAVE_NO_SEH) && !defined(__aarch64__)
    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.
	 * guaranteed Tk is always being unloaded from a stable condition.
	 */

#ifdef HAVE_NO_SEH
#   if defined(__aarch64__)
	/* Don't run TkFinalize(NULL) on mingw-w64 for ARM64, since we don't have corresponding assembler-code. */
#   ifdef __WIN64
#   elif defined(_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"
	    "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.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkWin3d.c --
 *
 *	This file contains the platform specific routines for drawing 3D
 *	borders in the Windows 95 style.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * 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.
 */

#include "tkWinInt.h"
#include "tk3d.h"
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+







 *
 *----------------------------------------------------------------------
 */

TkBorder *
TkpGetBorder(void)
{
    WinBorder *borderPtr = (WinBorder *)ckalloc(sizeof(WinBorder));
    WinBorder *borderPtr = ckalloc(sizeof(WinBorder));

    borderPtr->light2ColorPtr = NULL;
    borderPtr->dark2ColorPtr = NULL;
    return (TkBorder *) borderPtr;
}

/*
Changes to win/tkWinButton.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkWinButton.c --
 *
 *	This file implements the Windows specific portion of the button
 *	widgets.
 *
 * Copyright (c) 1996-1998 by Sun Microsystems, Inc.
 * Copyright (c) 1996-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.
 */

#define OEMRESOURCE
#include "tkWinInt.h"
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196







-
+







 */

void
TkpButtonSetDefaults(void)
{
    int width = GetSystemMetrics(SM_CXEDGE);
	if (width > 0) {
	    sprintf(tkDefButtonBorderWidth, "%d", width);
	    snprintf(tkDefButtonBorderWidth, sizeof(tkDefButtonBorderWidth), "%d", width);
	}
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateButton --
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
204
205
206
207
208
209
210

211
212
213

214
215
216
217
218
219
220







-
+


-







 *	Registers an event handler for the widget.
 *
 *----------------------------------------------------------------------
 */

TkButton *
TkpCreateButton(
    Tk_Window tkwin)
    TCL_UNUSED(Tk_Window))
{
    WinButton *butPtr;
    (void)tkwin;

    butPtr = (WinButton *)ckalloc(sizeof(WinButton));
    butPtr->hwnd = NULL;
    return (TkButton *) butPtr;
}

/*
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
321
322
323
324
325
326
327

328
329
330
331
332
333
334







-







    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. */
    int textXOffset = 0, textYOffset = 0;
				/* Text offsets for use with compound buttons
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
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







-

-
-
-
-
+
+
+
+
+

-
-
+
+
-
-
+

-
-
-
-







     * Draw the focus ring. If this is a push button then we need to put it
     * around the inner edge of the border, otherwise we put it around the
     * text. The text offsets are only non-zero when this is a compound
     * button.
     */

    if (drawRing && butPtr->flags & GOT_FOCUS && butPtr->type != TYPE_LABEL) {
	dc = TkWinGetDrawableDC(butPtr->display, pixmap, &state);
	if (butPtr->type == TYPE_BUTTON || !butPtr->indicatorOn) {
	    rect.top = butPtr->borderWidth + 1 + defaultWidth;
	    rect.left = rect.top;
	    rect.right = Tk_Width(tkwin) - rect.left;
	    rect.bottom = Tk_Height(tkwin) - rect.top;
	    int dottedWidth = butPtr->borderWidth + 1 + defaultWidth;
	    TkWinDrawDottedRect(butPtr->display, pixmap, gc->foreground,
		    dottedWidth, dottedWidth,
		    Tk_Width(tkwin) - 2*dottedWidth,
		    Tk_Height(tkwin) - 2*dottedWidth);
	} else {
	    rect.top = y-1 + textYOffset;
	    rect.left = x-1 + textXOffset;
	    TkWinDrawDottedRect(butPtr->display, pixmap, gc->foreground,
		    x-1 + textXOffset, y-1 + textYOffset,
	    rect.right = x+butPtr->textWidth + 1 + textXOffset;
	    rect.bottom = y+butPtr->textHeight + 2 + textYOffset;
		    butPtr->textWidth + 2, butPtr->textHeight + 3);
	}
	SetTextColor(dc, gc->foreground);
	SetBkColor(dc, gc->background);
	DrawFocusRect(dc, &rect);
	TkWinReleaseDrawableDC(pixmap, dc, &state);
    }

    y += height/2;

    /*
     * Draw the indicator for check buttons and radio buttons. At this point x
     * and y refer to the top-left corner of the text or image or bitmap.
1299
1300
1301
1302
1303
1304
1305
1306

1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1292
1293
1294
1295
1296
1297
1298

1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312







-
+













	    }
	    Tcl_ServiceAll();
	    return 0;
	}
    }
    /* FALLTHRU */
    default:
	if (TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	if (Tk_TranslateWinEvent(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:
 */
Changes to win/tkWinClipboard.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkWinClipboard.c --
 *
 *	This file contains functions for managing the clipboard.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 * 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.
 */

#include "tkWinInt.h"
#include "tkSelect.h"
51
52
53
54
55
56
57




58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67




68
69
70
71
72
73
74







+
+
+
+






-
-
-
-







{
    char *data, *destPtr;
    Tcl_DString ds;
    HGLOBAL handle;
    Tcl_Encoding encoding;
    int result, locale, noBackslash = 0;

    if ((selection != Tk_InternAtom(tkwin, "CLIPBOARD"))
	    || (target != XA_STRING)) {
	goto error;
    }
    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;
223
224
225
226
227
228
229
230

231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
223
224
225
226
227
228
229

230
231
232

233
234
235
236


237
238
239
240
241
242
243







-
+


-
+



-
-







 *	Empties the system clipboard, and claims ownership.
 *
 *----------------------------------------------------------------------
 */

int
XSetSelectionOwner(
    Display *display,
    TCL_UNUSED(Display *),
    Atom selection,
    Window owner,
    Time time)
    TCL_UNUSED(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;
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285

286
287
288
289
290
291
292







-
+







-







 *
 *----------------------------------------------------------------------
 */

void
TkWinClipboardRender(
    TkDisplay *dispPtr,
    UINT format)
    TCL_UNUSED(UINT))
{
    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;
	}
    }
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349















350
351
352
353
354
355
356
325
326
327
328
329
330
331















332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		}
		*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);
    Tcl_DStringInit(&ds);
    Tcl_UtfToWCharDString(rawText, -1, &ds);
    ckfree(rawText);
    handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
	    Tcl_DStringLength(&ds) + 2);
    if (!handle) {
	Tcl_DStringFree(&ds);
	return;
    }
    buffer = (char *)GlobalLock(handle);
    memcpy(buffer, Tcl_DStringValue(&ds),
	    Tcl_DStringLength(&ds) + 2);
    GlobalUnlock(handle);
    Tcl_DStringFree(&ds);
    SetClipboardData(CF_UNICODETEXT, handle);
}

/*
 *----------------------------------------------------------------------
 *
 * TkSelUpdateClipboard --
 *
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
380
381
382
362
363
364
365
366
367
368

369
370
371

372
373
374
375
376
377
378







-
+


-







 *
 *----------------------------------------------------------------------
 */

void
TkSelUpdateClipboard(
    TkWindow *winPtr,
    TkClipboardTarget *targetPtr)
    TCL_UNUSED(TkClipboardTarget *))
{
    HWND hwnd = TkWinGetHWND(winPtr->window);
    (void)targetPtr;

    UpdateClipboard(hwnd);
}

/*
 *----------------------------------------------------------------------
 *
449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
464
465
466
467
445
446
447
448
449
450
451

452
453

454
455
456
457
458
459
460
461
462







-
+

-









 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkSelPropProc(
    XEvent *eventPtr)	/* X PropertyChange event. */
    TCL_UNUSED(XEvent *))	/* X PropertyChange event. */
{
    (void)eventPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to win/tkWinColor.c.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
54
55
56
57
58
59
60

61
62
63
64
65
66
67







-







    {"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}
};

/*
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
296
297
298
299
300
301
302

303
304
305
306
307
308
309

310
311
312
313
314
315
316







-
+






-







 *	Allocates a new color in the palette.
 *
 *----------------------------------------------------------------------
 */

int
XAllocColor(
    Display *display,
    TCL_UNUSED(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) {
398
399
400
401
402
403
404
405

406
407
408
409

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
396
397
398
399
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.
 *
 *----------------------------------------------------------------------
 */

int
XFreeColors(
    Display *display,
    TCL_UNUSED(Display *),
    Colormap colormap,
    unsigned long *pixels,
    int npixels,
    unsigned long planes)
    TCL_UNUSED(unsigned long))
{
    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) {
	/*
472
473
474
475
476
477
478
479
480
481
482




483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
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







-
-
-
-
+
+
+
+









-
-
-
-







 *	Allocates an empty palette and color list.
 *
 *----------------------------------------------------------------------
 */

Colormap
XCreateColormap(
    Display *display,
    Window w,
    Visual *visual,
    int alloc)
    TCL_UNUSED(Display *),
    TCL_UNUSED(Window),
    TCL_UNUSED(Visual *),
    TCL_UNUSED(int))
{
    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;
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
555
556
557
531
532
533
534
535
536
537

538
539
540
541

542
543
544
545
546
547
548







-
+



-







 *	palette must not be selected into a device context when this occurs.
 *
 *----------------------------------------------------------------------
 */

int
XFreeColormap(
    Display *display,
    TCL_UNUSED(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;
Changes to win/tkWinConfig.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
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32






-
+

















-
+







/*
 * tkWinConfig.c --
 *
 *	This module implements the Windows system defaults for the
 *	configuration package.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright (c) 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkWinInt.h"


/*
 *----------------------------------------------------------------------
 *
 * TkpGetSystemDefault --
 *
 *	Given a dbName and className for a configuration option, return a
 *	string representation of the option.
 *
 * Results:
 *	Returns a Tk_Uid that is the string identifier that identifies this
 *	Returns a Tcl_Obj* with the string identifier that identifies this
 *	option. Returns NULL if there are no system defaults that match this
 *	pair.
 *
 * Side effects:
 *	None, once the package is initialized.
 *
 *----------------------------------------------------------------------
Changes to win/tkWinCursor.c.
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49







-
+







#endif

/*
 * The table below is used to map from the name of a predefined cursor to its
 * resource identifier.
 */

static struct CursorName {
static const struct CursorName {
    const char *name;
    LPCTSTR id;
} cursorNames[] = {
    {"starting",		IDC_APPSTARTING},
    {"arrow",			IDC_ARROW},
    {"ibeam",			IDC_IBEAM},
    {"icon",			IDC_ICON},
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123
124
92
93
94
95
96
97
98

99
100
101
102

103
104
105

106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123







-
+



-



-
+









-
+







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. */
{
    struct CursorName *namePtr;
    const 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.
     * 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 = 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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
197
198
199
200
201
202
203










204
205
206
207
208
209
210







-
-
-
-
-
-
-
-
-
-







    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 --
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
221
222
223
224
225
226
227


228
229
230
231
232
233
234







-
-







 *----------------------------------------------------------------------
 */

void
TkpFreeCursor(
    TkCursor *cursorPtr)
{
    (void)cursorPtr;

    /* TkWinCursor *winCursorPtr = (TkWinCursor *) cursorPtr; */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetCursor --
Changes to win/tkWinDefault.h.
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90

91
92
93
94
95
96
97
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90

91
92
93
94
95
96
97
98







+









-
+















-
+


-
+







#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_LABEL_FG			NORMAL_FG
#define DEF_BUTTON_FG			NORMAL_FG
#define DEF_CHKRAD_FG			TEXT_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		HIGHLIGHT
#define DEF_LABEL_HIGHLIGHT_WIDTH	"0"
#define DEF_BUTTON_HIGHLIGHT_WIDTH	"1"
#define DEF_BUTTON_IMAGE		NULL
#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		NULL
#define DEF_BUTTON_SELECT_IMAGE		((char *) NULL)
#define DEF_BUTTON_STATE		"normal"
#define DEF_LABEL_TAKE_FOCUS		"0"
#define DEF_BUTTON_TAKE_FOCUS		NULL
#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
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+







#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_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
154
155
156
157
158
159
160


161
162
163
164
165
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		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_SHOW			((char *) NULL)
#define DEF_ENTRY_STATE			"normal"
#define DEF_ENTRY_TAKE_FOCUS		NULL
#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_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
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
252
253




254
255
256

257
258
259


260
261

262
263
264


265
266
267

268
269
270


271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299


300
301
302
303
304
305
306
233
234
235
236
237
238
239

240
241
242
243
244
245
246




247
248
249
250
251
252

253
254


255
256
257

258
259


260
261
262
263

264
265


266
267
268

269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293


294
295
296
297
298
299
300
301
302







-
+






-
-
-
-
+
+
+
+


-
+

-
-
+
+

-
+

-
-
+
+


-
+

-
-
+
+

-
+











-













-
-
+
+







#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_TAKE_FOCUS		((char *) 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_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		NULL
#define DEF_MENU_ENTRY_COMMAND		((char *) NULL)
#define DEF_MENU_ENTRY_COMPOUND 	"none"
#define DEF_MENU_ENTRY_FG		NULL
#define DEF_MENU_ENTRY_FONT		NULL
#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		NULL
#define DEF_MENU_ENTRY_IMAGE		((char *) NULL)
#define DEF_MENU_ENTRY_INDICATOR	"1"
#define DEF_MENU_ENTRY_LABEL		NULL
#define DEF_MENU_ENTRY_MENU		NULL
#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	NULL
#define DEF_MENU_ENTRY_SELECT_IMAGE	((char *) NULL)
#define DEF_MENU_ENTRY_STATE		"normal"
#define DEF_MENU_ENTRY_VALUE		NULL
#define DEF_MENU_ENTRY_CHECK_VARIABLE	NULL
#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		NULL
#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_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_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
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330







-
+







#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_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"
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440







-
+







#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_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
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467







-
+







#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_TAKE_FOCUS	((char *) NULL)
#define DEF_SCROLLBAR_TROUGH_COLOR	TROUGH
#define DEF_SCROLLBAR_TROUGH_MONO	WHITE
#define DEF_SCROLLBAR_WIDTH		"10"

/*
 * Defaults for texts:
 */
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
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







-
+














-
+







#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_INACTIVE_SELECT_BG_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_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	""

/*
Changes to win/tkWinDialog.c.
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
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







-
+






-
+












-
+







 */

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,
static int              ParseOFNOptions(void *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,
static int 		GetFileName(void *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 void		SetTkDialog(void *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);
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756







-
+







 *	application invokes the "tk_chooseColor" command.
 *
 *-------------------------------------------------------------------------
 */

int
Tk_ChooseColorObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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;
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
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







-
+

















-
-
+
+














-
+







	    dwCustColors[i] = RGB(255-i * 10, i, i * 10);
	}
	oldColor = RGB(0xa0, 0xa0, 0xa0);
	inited = 1;
    }

    parent			= tkwin;
    chooseColor.lStructSize	= sizeof(CHOOSECOLOR);
    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_GetIndexFromObjStruct(interp, optionPtr, optionStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
	if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings,
		"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;

	    colorPtr = Tk_GetColor(interp, tkwin, string);
	    colorPtr = Tk_AllocColorFromObj(interp, tkwin, valuePtr);
	    if (colorPtr == NULL) {
		return TCL_ERROR;
	    }
	    chooseColor.rgbResult = RGB(colorPtr->red / 0x100,
		    colorPtr->green / 0x100, colorPtr->blue / 0x100);
	    break;
	}
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
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







-
+





-
+
-







-
+







 *----------------------------------------------------------------------
 */

static UINT CALLBACK
ColorDlgHookProc(
    HWND hDlg,			/* Handle to the color dialog. */
    UINT uMsg,			/* Type of message. */
    WPARAM wParam,		/* First message parameter. */
    TCL_UNUSED(WPARAM),	/* First message parameter. */
    LPARAM lParam)		/* Second message parameter. */
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *title;
    CHOOSECOLOR *ccPtr;
    CHOOSECOLORW *ccPtr;
    (void)wParam;

    if (WM_INITDIALOG == uMsg) {

	/*
	 * Set the title string of the dialog.
	 */

	ccPtr = (CHOOSECOLOR *) lParam;
	ccPtr = (CHOOSECOLORW *) 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));
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
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







-
+















-
+










-
+

-
+



-
+


-
+






-
+







    }
    return FALSE;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetOpenFileCmd --
 * Tk_GetOpenFileObjCmd --
 *
 *	This function implements the "open file" dialog box for the Windows
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	A dialog window is created the first this function is called.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetOpenFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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 --
 * Tk_GetSaveFileObjCmd --
 *
 *	Same as Tk_GetOpenFileCmd but opens a "save file" dialog box
 *	Same as Tk_GetOpenFileObjCmd but opens a "save file" dialog box
 *	instead
 *
 * Results:
 *	Same as Tk_GetOpenFileCmd.
 *	Same as Tk_GetOpenFileObjCmd.
 *
 * Side effects:
 *	Same as Tk_GetOpenFileCmd.
 *	Same as Tk_GetOpenFileObjCmd.
 *
 *----------------------------------------------------------------------
 */

int
Tk_GetSaveFileObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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);
}

1025
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1024
1025
1026
1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038







-
+







 *	Returns option values in *optsPtr. Note these may include string
 *      pointers into objv[]
 *----------------------------------------------------------------------
 */

static int
ParseOFNOptions(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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;
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
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







-
+













-
-
+
+







	{"-parent",		FILE_PARENT},
	{"-title",		FILE_TITLE},
	{"-typevariable",	FILE_TYPEVARIABLE},
	{NULL,			FILE_DEFAULT/*ignored*/ }
    };
    static const struct Options dirOptions[] = {
	{"-initialdir", FILE_INITDIR},
        {"-mustexist",  FILE_MUSTEXIST},
	{"-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;
    memset(optsPtr, 0, 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;
1138
1139
1140
1141
1142
1143
1144
1145
1146


1147
1148
1149
1150
1151
1152
1153
1154
1137
1138
1139
1140
1141
1142
1143


1144
1145

1146
1147
1148
1149
1150
1151
1152







-
-
+
+
-







                                      &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),
		    Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), 0,
		    NULL, (char *)&optsPtr->file[0], sizeof(optsPtr->file), NULL, NULL, NULL);
                              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;
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
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







-
-
-
-
-
+
+
+
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+

-
-
-
-
-
-
+
+
+
+
+
+







{
    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 ? */
	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,
	    /* 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);
                                          (void **) &fdlgPtr);
                    if (SUCCEEDED(hr)) {
                        fdlgPtr->lpVtbl->Release(fdlgPtr);
		    if (SUCCEEDED(hr)) {
			fdlgPtr->lpVtbl->Release(fdlgPtr);

                        /* Looks like we have all we need */
                        tsdPtr->newFileDialogsState = FDLG_STATE_USE_NEW;
                    }
                }
            }
        }
			/* Looks like we have all we need */
			tsdPtr->newFileDialogsState = FDLG_STATE_USE_NEW;
		    }
		}
	    }
	}
    }

    return (tsdPtr->newFileDialogsState == FDLG_STATE_USE_NEW);
}

/*
 *----------------------------------------------------------------------
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
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







-
+













-
+







    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));
    memset(&ofnData, 0, 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));
    memset(&ofn, 0, 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;
1654
1655
1656
1657
1658
1659
1660
1661
1662


1663
1664
1665
1666
1667
1668
1669
1651
1652
1653
1654
1655
1656
1657


1658
1659
1660
1661
1662
1663
1664
1665
1666







-
-
+
+








	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_DStringInit(&dirString);
	    Tcl_UtfToWCharDString(Tcl_DStringValue(&cwd),
		    Tcl_DStringLength(&cwd), &dirString);
	}
	Tcl_DStringFree(&cwd);
    }
    ofn.lpstrInitialDir = (WCHAR *) Tcl_DStringValue(&dirString);

    if (optsPtr->titleObj != NULL) {
1867
1868
1869
1870
1871
1872
1873
1874

1875
1876
1877
1878
1879
1880
1881
1864
1865
1866
1867
1868
1869
1870

1871
1872
1873
1874
1875
1876
1877
1878







-
+







 *	See user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
GetFileName(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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;
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
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







-
+

















-
+






-









/*
 *-------------------------------------------------------------------------
 *
 * OFNHookProc --
 *
 *	Dialog box hook function. This is used to sets the "tk_dialog"
 *	Dialog box hook function. This is used to set the "tk_dialog"
 *	variable for test/debugging when the dialog is ready to receive
 *	messages. When multiple file selection is enabled this function
 *	is used to process the list of names.
 *
 * Results:
 *	Returns 0 to allow default processing of messages to occur.
 *
 * Side effects:
 *	None.
 *
 *-------------------------------------------------------------------------
 */

static UINT APIENTRY
OFNHookProc(
    HWND hdlg,			/* Handle to child dialog window. */
    UINT uMsg,			/* Message identifier */
    WPARAM wParam,		/* Message parameter */
    TCL_UNUSED(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;

	/*
2037
2038
2039
2040
2041
2042
2043
2044

2045
2046
2047
2048
2049
2050
2051
2033
2034
2035
2036
2037
2038
2039

2040
2041
2042
2043
2044
2045
2046
2047







-
+







    } 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);
	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);
	    }
2112
2113
2114
2115
2116
2117
2118
2119

2120
2121
2122
2123
2124

2125
2126
2127
2128
2129
2130
2131
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117
2118
2119

2120
2121
2122
2123
2124
2125
2126
2127







-
+




-
+







	*p++ = '.';
	*p++ = '*';
	*p++ = '\0';
	*p++ = '\0';
	*p = '\0';

    } else {
	TkSizeT len;
	int len;

	if (valuePtr == NULL) {
	    len = 0;
	} else {
	    (void) TkGetStringFromObj(valuePtr, &len);
	    (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"
	 *
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
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







-
+




















-
+

-
+







	 * characters.
	 */

	*p++ = '\0';
	*p = '\0';
    }

    Tcl_DStringAppend(dsPtr, filterStr, (int) (p - filterStr));
    Tcl_DStringAppend(dsPtr, filterStr, 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);
                ckfree(dlgFilterPtr[dw].pszName);
            if (dlgFilterPtr[dw].pszSpec != NULL)
                ckfree((char *)dlgFilterPtr[dw].pszSpec);
                ckfree(dlgFilterPtr[dw].pszSpec);
        }
        ckfree(dlgFilterPtr);
    }
}

/*
 *----------------------------------------------------------------------
2301
2302
2303
2304
2305
2306
2307
2308
2309


2310
2311
2312
2313
2314
2315
2316
2297
2298
2299
2300
2301
2302
2303


2304
2305
2306
2307
2308
2309
2310
2311
2312







-
-
+
+







	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);
	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);

	/*
2330
2331
2332
2333
2334
2335
2336
2337
2338


2339
2340
2341
2342
2343
2344
2345
2326
2327
2328
2329
2330
2331
2332


2333
2334
2335
2336
2337
2338
2339
2340
2341







-
-
+
+







		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);
	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);
    }
2425
2426
2427
2428
2429
2430
2431
2432

2433
2434
2435
2436
2437
2438
2439
2421
2422
2423
2424
2425
2426
2427

2428
2429
2430
2431
2432
2433
2434
2435







-
+







 * - -title is really -message.
 *
 *----------------------------------------------------------------------
 */

int
Tk_ChooseDirectoryObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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 */
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
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







-
+










-
+

-
+

-
-
+
+







        CleanupOFNOptions(&ofnOpts);
        return result;
    }

    /* Older dialogs */

    path[0] = '\0';
    ZeroMemory(&cdCBData, sizeof(ChooseDir));
    memset(&cdCBData, 0, 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);
	uniStr = (WCHAR *) Tcl_DStringValue(&tempString);

        /* Convert possible relative path to full path to keep dialog happy. */
	/* Convert possible relative path to full path to keep dialog happy. */

        GetFullPathNameW(uniStr, MAX_PATH, saveDir, NULL);
        wcsncpy(cdCBData.initDir, saveDir, MAX_PATH);
	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
     */
2707
2708
2709
2710
2711
2712
2713
2714

2715
2716
2717

2718
2719
2720
2721
2722
2723
2724
2703
2704
2705
2706
2707
2708
2709

2710
2711
2712

2713
2714
2715
2716
2717
2718
2719
2720







-
+


-
+







	 * -enablenonfolders can be used to allow non folders to be selected.
	 *
	 * Not called when user changes edit box directly.
	 */

	if (SHGetPathFromIDListW((LPITEMIDLIST) lParam, selDir)) {
	    SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, (LPARAM) selDir);
	    // enable the OK button
	    /* enable the OK button */
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1);
	} else {
	    // disable the OK button
	    /* disable the OK button */
	    SendMessageW(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0);
	}
	UpdateWindow(hwnd);
	return 1;

    case BFFM_INITIALIZED: {
	/*
2775
2776
2777
2778
2779
2780
2781
2782

2783
2784
2785
2786
2787
2788
2789
2790

2791
2792
2793
2794
2795
2796
2797
2771
2772
2773
2774
2775
2776
2777

2778
2779
2780
2781
2782
2783
2784
2785

2786
2787
2788
2789
2790
2791
2792
2793







-
+







-
+







 *	This function implements the MessageBox window for the Windows
 *	platform. See the user documentation for details on what it does.
 *
 * Results:
 *	See user documentation.
 *
 * Side effects:
 *	None. The MessageBox window will be destroy before this function
 *	None. The MessageBox window will be destroyed before this function
 *	returns.
 *
 *----------------------------------------------------------------------
 */

int
Tk_MessageBoxObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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;
2823
2824
2825
2826
2827
2828
2829
2830
2831


2832
2833
2834
2835
2836
2837
2838
2819
2820
2821
2822
2823
2824
2825


2826
2827
2828
2829
2830
2831
2832
2833
2834







-
-
+
+







    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) {
	if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings,
		"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;
3017
3018
3019
3020
3021
3022
3023
3024

3025
3026
3027
3028
3029
3030

3031
3032
3033
3034
3035
3036
3037
3013
3014
3015
3016
3017
3018
3019

3020
3021
3022
3023
3024
3025

3026
3027
3028
3029
3030
3031
3032
3033







-
+





-
+







 *	the test command 'tkwinevent debug 1'.
 *
 * ----------------------------------------------------------------------
 */

static void
SetTkDialog(
    ClientData clientData)
    void *clientData)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    char buf[32];

    sprintf(buf, "0x%" TCL_Z_MODIFIER "x", (size_t)clientData);
    snprintf(buf, sizeof(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.
 */

3082
3083
3084
3085
3086
3087
3088
3089

3090
3091
3092
3093
3094
3095
3096
3078
3079
3080
3081
3082
3083
3084

3085
3086
3087
3088
3089
3090
3091
3092







-
+







    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));
    Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewIntObj(pt));
    if (plf->lfWeight >= 700) {
	Tcl_ListObjAppendElement(NULL, resObj, Tcl_NewStringObj("bold", -1));
    }
    if (plf->lfItalic) {
	Tcl_ListObjAppendElement(NULL, resObj,
		Tcl_NewStringObj("italic", -1));
    }
3147
3148
3149
3150
3151
3152
3153
3154

3155
3156
3157
3158
3159
3160
3161
3143
3144
3145
3146
3147
3148
3149

3150
3151
3152
3153
3154
3155
3156
3157







-
+







static UINT_PTR CALLBACK
HookProc(
    HWND hwndDlg,
    UINT msg,
    WPARAM wParam,
    LPARAM lParam)
{
    CHOOSEFONT *pcf = (CHOOSEFONT *) lParam;
    CHOOSEFONTW *pcf = (CHOOSEFONTW *) 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;
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
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







-
+





-
+

















-
+







	if (IsWindow(hwndCtrl)) {
	    EnableWindow(hwndCtrl, FALSE);
	}
	hwndCtrl = GetDlgItem(hwndDlg, 0x473);
	if (IsWindow(hwndCtrl)) {
	    EnableWindow(hwndCtrl, FALSE);
	}
	Tk_SendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	return 1; /* we handled the message */
    }

    if (WM_DESTROY == msg) {
	phd->hwnd = NULL;
	Tk_SendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL);
	TkSendVirtualEvent(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);
	    TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL);
	}
	return 1;
    }
    return 0; /* pass on for default processing */
}

/*
3261
3262
3263
3264
3265
3266
3267
3268

3269
3270
3271
3272
3273
3274
3275
3257
3258
3259
3260
3261
3262
3263

3264
3265
3266
3267
3268
3269
3270
3271







-
+







	if (hdPtr->cmdObj) {
	    resObj = hdPtr->cmdObj;
	} else {
	    resObj = Tcl_NewStringObj("", 0);
	}
	break;
    case FontchooserVisible:
	resObj = Tcl_NewWideIntObj((hdPtr->hwnd != NULL) && IsWindow(hdPtr->hwnd));
	resObj = Tcl_NewBooleanObj((hdPtr->hwnd != NULL) && IsWindow(hdPtr->hwnd));
	break;
    default:
	resObj = Tcl_NewStringObj("", 0);
    }
    return resObj;
}

3288
3289
3290
3291
3292
3293
3294
3295

3296
3297
3298
3299
3300
3301

3302

3303
3304
3305
3306
3307
3308
3309
3284
3285
3286
3287
3288
3289
3290

3291
3292
3293
3294
3295
3296
3297
3298

3299
3300
3301
3302
3303
3304
3305
3306







-
+






+
-
+







 *	Per-interp data structure may be modified
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserConfigureCmd(
    ClientData clientData,	/* Main window */
    void *clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Window tkwin = (Tk_Window)clientData;
    HookData *hdPtr = NULL;
    int i;
    int i, r = TCL_OK;
    int r = TCL_OK;
    static const char *const optionStrings[] = {
	"-parent", "-title", "-font", "-command", "-visible", NULL
    };

    hdPtr = (HookData *)Tcl_GetAssocData(interp, "::tk::fontchooser", NULL);

    /*
3324
3325
3326
3327
3328
3329
3330
3331
3332


3333
3334
3335
3336
3337
3338
3339
3321
3322
3323
3324
3325
3326
3327


3328
3329
3330
3331
3332
3333
3334
3335
3336







-
-
+
+







	}
	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) {
	if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
		"option", 0, &optionIndex) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (objc == 2) {
	    /*
	     * If one option and no arg - return the current value.
	     */

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
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







-
+

-
-
+
+








-
-














-
-
+
+

-
+







 *	additional state.
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserShowCmd(
    ClientData clientData,	/* Main window */
    void *clientData,	/* Main window */
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    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));
    memset(&cf, 0, sizeof(CHOOSEFONTW));
    memset(&lf, 0, sizeof(LOGFONTW));
    lf.lfCharSet = DEFAULT_CHARSET;
    cf.lStructSize = sizeof(CHOOSEFONT);
    cf.lStructSize = sizeof(CHOOSEFONTW);
    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;
3521
3522
3523
3524
3525
3526
3527
3528

3529
3530
3531
3532
3533
3534
3535
3516
3517
3518
3519
3520
3521
3522

3523
3524
3525
3526
3527
3528
3529
3530







-
+







    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);
		TkSendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged", NULL);
	    }
	}
	Tcl_SetServiceMode(oldMode);
	EnableWindow(cf.hwndOwner, 1);
    }

    ReleaseDC(cf.hwndOwner, hdc);
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
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







-
+

-
-
+
+


-
-
-



















-
+
+
+


-







 *	destroy the dialog
 *
 * ----------------------------------------------------------------------
 */

static int
FontchooserHideCmd(
    ClientData dummy,	/* Main window */
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
    TCL_UNUSED(int),
    TCL_UNUSED(Tcl_Obj *const *))
{
    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)
DeleteHookData(
    void *clientData,
    TCL_UNUSED(Tcl_Interp *))
{
    HookData *hdPtr = (HookData *)clientData;
    (void)dummy;

    if (hdPtr->parentObj) {
	Tcl_DecrRefCount(hdPtr->parentObj);
    }
    if (hdPtr->fontObj) {
	Tcl_DecrRefCount(hdPtr->fontObj);
    }
3615
3616
3617
3618
3619
3620
3621
3622



3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
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







-
+
+
+


-













    { "configure", FontchooserConfigureCmd, NULL },
    { "show", FontchooserShowCmd, NULL },
    { "hide", FontchooserHideCmd, NULL },
    { NULL, NULL, NULL }
};

int
TkInitFontchooser(Tcl_Interp *interp, ClientData dummy)
TkInitFontchooser(
    Tcl_Interp *interp,
    TCL_UNUSED(void *))
{
    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:
 */
Changes to win/tkWinDraw.c.
240
241
242
243
244
245
246
247

248
249
250
251
252
253
254
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254







-
+







     * 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);
	tsdPtr->winPoints = ckalloc(sizeof(POINT) * npoints);
	if (tsdPtr->winPoints == NULL) {
	    tsdPtr->nWinPoints = -1;
	    return NULL;
	}
	tsdPtr->nWinPoints = npoints;
    }

365
366
367
368
369
370
371
372

373
374
375
376
377
378
379
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379







-
+







    unsigned long plane)
{
    HDC srcDC, destDC;
    TkWinDCState srcState, destState;
    HBRUSH bgBrush, fgBrush, oldBrush;
    TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask;

    display->request++;
    LastKnownRequestProcessed(display)++;

    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
    }

    srcDC = TkWinGetDrawableDC(display, src, &srcState);

408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
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);
	    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
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);
	    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.
	     */
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
484
485
486
487
488
489
490

491
492
493
494
495
496
497
498







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkPutImage, XPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of of the
 *	Copies a subimage from an in-memory image to a rectangle of the
 *	specified drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
516
517
518
519
520
521
522
523

524
525
526
527
528
529
530
516
517
518
519
520
521
522

523
524
525
526
527
528
529
530







-
+







{
    HDC dc, dcMem;
    TkWinDCState state;
    BITMAPINFO *infoPtr;
    HBITMAP bitmap;
    char *data;

    display->request++;
    LastKnownRequestProcessed(display)++;

    dc = TkWinGetDrawableDC(display, d, &state);
    SetROP2(dc, tkpWinRopModes[gc->function]);
    dcMem = CreateCompatibleDC(dc);

    if (image->bits_per_pixel == 1) {
	/*
549
550
551
552
553
554
555
556

557
558
559

560
561
562
563
564
565
566
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)
	    infoPtr = ckalloc(sizeof(BITMAPINFOHEADER)
		    + sizeof(RGBQUAD)*ncolors);
	} else {
	    infoPtr = (BITMAPINFO *)ckalloc(sizeof(BITMAPINFOHEADER));
	    infoPtr = 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;
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
583
584
585
586
587
588
589



590

591
592
593
594
595
596
597
598
599

600
601
602
603
604
605
606







-
-
-

-
+








-







	}
	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);
    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;
}

#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. */
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
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







-
+











-
+








	/*
	 * 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);
	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.
	 */

	while (nrectangles-- > 0) {
	    bitmap = CreateCompatibleBitmap(dc, rectangles[0].width,
		    rectangles[0].height);
	    oldBitmap = (HBITMAP)SelectObject(dcMem, bitmap);
	    oldBitmap = 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);
715
716
717
718
719
720
721
722
723


724
725
726
727
728
729
730
711
712
713
714
715
716
717


718
719
720
721
722
723
724
725
726







-
-
+
+







		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);
	    HPEN oldPen = SelectObject(dc, newPen);
	    oldBrush = 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;
	    }
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
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







-
+







-
+

-
+



















-
+







	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));
	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 = (HBITMAP)SelectObject(dcMem, CreateCompatibleBitmap(dc, width,
	oldBitmap = SelectObject(dcMem, CreateCompatibleBitmap(dc, width,
		height));
	oldPen = (HPEN)SelectObject(dcMem, pen);
	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 = (HBRUSH)SelectObject(dcMem, CreateSolidBrush(gc->foreground));
	oldMemBrush = 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.
898
899
900
901
902
903
904
905
906


907
908
909
910
911
912
913
894
895
896
897
898
899
900


901
902
903
904
905
906
907
908
909







-
-
+
+







	}

	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));
	oldPen = SelectObject(dc, pen);
	oldBrush = 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);
    }
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
979
980
981
982
983
984
985

986
987
988
989
990
991
992

993
994
995
996
997
998
999
1000







-







-
+







    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);
    pen = GetStockObject(NULL_PEN);
    RenderObject(dc, gc, points, npoints, mode, pen, Polygon);

    TkWinReleaseDrawableDC(d, dc, &state);
    return Success;
}

/*
1035
1036
1037
1038
1039
1040
1041
1042
1043


1044
1045
1046
1047
1048
1049
1050
1030
1031
1032
1033
1034
1035
1036


1037
1038
1039
1040
1041
1042
1043
1044
1045







-
-
+
+







	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));
    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);
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
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







-
+














-
+







    Display *display,
    Drawable d,
    GC gc,
    int x, int y,
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;
    LastKnownRequestProcessed(display)++;

    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++;
    LastKnownRequestProcessed(display)++;

    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;
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
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







-
+














-
+







    Display *display,
    Drawable d,
    GC gc,
    int x, int y,
    unsigned int width, unsigned int height,
    int start, int extent)
{
    display->request++;
    LastKnownRequestProcessed(display)++;

    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++;
    LastKnownRequestProcessed(display)++;

    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;
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
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







-
+












-
+







    /*
     * 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);
    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 = (HBRUSH)SelectObject(dc, brush);
	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
1395
1396
1397
1398
1399
1400
1401

1402
1403
1404
1405

1406
1407
1408
1409
1410
1411
1412







-
+



-







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. */
    TkRegion 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;
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+













-
+

-





-
+











TkpDrawHighlightBorder(
    Tk_Window tkwin,
    GC fgGC,
    GC bgGC,
    int highlightWidth,
    Drawable drawable)
{
    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinDrawDottedRect --
 *
 *      This function draws a dotted rectangle, used as focus ring of Ttk
 *      widgets and for rendering the active element of a listbox.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      A dotted rectangle is drawn in the specified Drawable.
 *
 *----------------------------------------------------------------------
 */

    (void)bgGC;

    TkDrawInsetFocusHighlight(tkwin, fgGC, highlightWidth, drawable, 0);
}

void
TkWinDrawDottedRect(
    Display *disp,		/* Display containing the dotted rectangle. */
    Drawable d,			/* Where to draw the rectangle (typically a
				 * pixmap for double buffering). */
    long pixel,			/* Color to use for drawing the rectangle.  If
				 * pixel < 0 then the black color and the
				 * foreground mix mode R2_NOT are used. */
    int x, int y,		/* Coordinates of the top-left corner. */
    int width, int height)	/* Width & height, _including the border_. */
{
    TkWinDCState state;
    HDC dc;
    LOGBRUSH lb;
    HPEN pen;
    int widthMod2 = width % 2, heightMod2 = height % 2;
    int x2 = x + width - 1, y2 = y + height - 1;

    dc = TkWinGetDrawableDC(disp, d, &state);

    lb.lbStyle = BS_SOLID;
    lb.lbColor = pixel < 0 ? RGB(0, 0, 0) : (COLORREF)pixel;
    lb.lbHatch = 0;

    if (pixel < 0) {
	SetROP2(dc, R2_NOT);
	SetBkMode(dc, TRANSPARENT);
    }

    pen = ExtCreatePen(PS_COSMETIC | PS_ALTERNATE, 1, &lb, 0, NULL);
    SelectObject(dc, pen);
    SelectObject(dc, GetStockObject(NULL_BRUSH));

    if (widthMod2 == 0 && heightMod2 == 0) {
	MoveToEx(dc, x+1, y,  NULL);	LineTo(dc, x2,   y);	/* N */
	MoveToEx(dc, x+2, y2, NULL);	LineTo(dc, x2+1, y2);	/* S */
	MoveToEx(dc, x,  y+2, NULL);	LineTo(dc, x,  y2+1);	/* W */
	MoveToEx(dc, x2, y+1, NULL);	LineTo(dc, x2, y2);	/* E */
    } else {
	int dx = widthMod2, dy = heightMod2;

	MoveToEx(dc, x+1, y,  NULL);	LineTo(dc, x2+dx, y);	/* N */
	MoveToEx(dc, x+1, y2, NULL);	LineTo(dc, x2+dx, y2);	/* S */
	MoveToEx(dc, x,  y+1, NULL);	LineTo(dc, x,  y2+dy);	/* W */
	MoveToEx(dc, x2, y+1, NULL);	LineTo(dc, x2, y2+dy);	/* E */
    }

    DeleteObject(pen);
    TkWinReleaseDrawableDC(d, dc, &state);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrameEx --
 * TkpDrawFrame --
 *
 *	This function draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrameEx(
TkpDrawFrame(
    Tk_Window tkwin,
    Drawable drawable,
    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    Tk_Fill3DRectangle(tkwin, drawable, border, highlightWidth,
    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.
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79







-
+







 *----------------------------------------------------------------------
 */

void
TkWinCleanupContainerList(void)
{
    Container *nextPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (; tsdPtr->firstContainerPtr != NULL;
	    tsdPtr->firstContainerPtr = nextPtr) {
	nextPtr = tsdPtr->firstContainerPtr->nextPtr;
	ckfree(tsdPtr->firstContainerPtr);
    }
92
93
94
95
96
97
98

99
100
101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106





107
108
109
110
111
112
113







+


-
+




-
-
-
-
-







 *
 * Side effects:
 *	Currently it does not do anything.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
int
TkpTestembedCmd(
    ClientData dummy,
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    (void)dummy;
    (void)interp;
    (void)objc;
    (void)objv;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_DetachEmbeddedWindow --
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183







-
+







	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {
	    /* empty body */
	}

	TkpWmSetState(winPtr, state);
	TkWmMapWindow(winPtr);
    }
    Tcl_Release(winPtr);
    Tcl_Release((ClientData)winPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpUseWindow --
 *
331
332
333
334
335
336
337
338
339


340
341
342
343
344
345
346
327
328
329
330
331
332
333


334
335
336
337
338
339
340
341
342







-
-
+
+







    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);
    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
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402







-
+




















-
+








    /*
     * 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 = 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);
	    ContainerEventProc, (ClientData) containerPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinEmbeddedEventProc --
 *
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1046
1047
1048
1049
1050
1051
1052


1053
1054
1055
1056
1057
1058
1059







-
-







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 --
1090
1091
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098
1099







-

+







     * Find the Container structure for this window work. Delete the
     * information about the embedded application and free the container's
     * record. The main container may be null. [Bug #476176]
     */

    prevPtr = NULL;
    containerPtr = tsdPtr->firstContainerPtr;
    if (containerPtr == NULL) return;
    while (1) {
	if (containerPtr == NULL) return;
	if (containerPtr->embeddedPtr == winPtr) {
	    containerPtr->embeddedHWnd = NULL;
	    containerPtr->embeddedPtr = NULL;
	    break;
	}
	if (containerPtr->parentPtr == winPtr) {
	    SendMessageW(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0);
Changes to win/tkWinFont.c.
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16








-
+







/*
 * 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.
 * 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 "tkWinInt.h"
#include "tkFont.h"
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132







-
+







				/* Builtin space for a limited number of
				 * SubFonts. */
    int numSubFonts;		/* Length of following array. */
    SubFont *subFontArray;	/* Array of SubFonts that have been loaded in
				 * 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
				 * InitFont() 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
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
401
402
403
404
405
406
407

408
409
410
411
412
413
414
415







-
+







    /*
     * 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));
    memset(&ncMetrics, 0, 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);
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
846
847
848
849
850
851
852

853
854
855
856
857
858
859
860







-
+







    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);
		    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) {
874
875
876
877
878
879
880
881

882
883
884
885
886
887
888
874
875
876
877
878
879
880

881
882
883
884
885
886
887
888







-
+







	/*
	 * 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);
		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;
1077
1078
1079
1080
1081
1082
1083
1084

1085
1086
1087
1088
1089
1090
1091
1077
1078
1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089
1090
1091







-
+







				 * string when drawing. */
{
    HDC dc;
    WinFont *fontPtr;
    TkWinDCState state;

    fontPtr = (WinFont *) gc->font;
    display->request++;
    LastKnownRequestProcessed(display)++;

    if (drawable == None) {
	return;
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);

1225
1226
1227
1228
1229
1230
1231
1232

1233
1234
1235
1236
1237
1238
1239
1225
1226
1227
1228
1229
1230
1231

1232
1233
1234
1235
1236
1237
1238
1239







-
+







    double angle)
{
    HDC dc;
    WinFont *fontPtr;
    TkWinDCState state;

    fontPtr = (WinFont *) gc->font;
    display->request++;
    LastKnownRequestProcessed(display)++;

    if (drawable == None) {
	return;
    }

    dc = TkWinGetDrawableDC(display, drawable, &state);

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
1412
1413
1414
1415
1416
1417
1418

1419
1420
1421
1422
1423
1424
1425
1426
1427
1428

1429
1430
1431
1432
1433
1434
1435







-
+









-







    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. */
    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. */
    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);
}

/*
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
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







-
-
+
+




















-
-
+
+







	 * 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,
			p - source, &runString);
		familyPtr->textOutProc(hdc, (int)(x-(double)tm.tmOverhang/2.0), 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,
		p - source, &runString);
	familyPtr->textOutProc(hdc, (int)(x-(double)tm.tmOverhang/2.0), y,
		(WCHAR *)Tcl_DStringValue(&runString),
		Tcl_DStringLength(&runString) >> familyPtr->isWideFont);
	Tcl_DStringFree(&runString);
    }
    SelectObject(hdc, oldFont);
}

1814
1815
1816
1817
1818
1819
1820
1821

1822
1823
1824
1825
1826
1827
1828
1813
1814
1815
1816
1817
1818
1819

1820
1821
1822
1823
1824
1825
1826
1827







-
+








    familyPtr->refCount = 2;

    familyPtr->segCount = LoadFontRanges(hdc, hFont, &familyPtr->startCount,
	    &familyPtr->endCount, &familyPtr->isSymbolFont);

    encoding = NULL;
    if (familyPtr->isSymbolFont != 0) {
    if (familyPtr->isSymbolFont) {
	/*
	 * Symbol fonts are handled specially. For instance, Unicode 0393
	 * (GREEK CAPITAL GAMMA) must be mapped to Symbol character 0047
	 * (GREEK CAPITAL GAMMA), because the Symbol font doesn't have a GREEK
	 * CAPITAL GAMMA at location 0393. If Tk interpreted the Symbol font
	 * using the Unicode encoding, it would decide that the Symbol font
	 * has no GREEK CAPITAL GAMMA, because the Symbol encoding (of course)
2542
2543
2544
2545
2546
2547
2548
















2549
2550
2551
2552
2553
2554
2555
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







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_DStringInit(&faceString);
    Tcl_UtfToWCharDString(faceName, -1, &faceString);

    /*
     * If the family exists, WinFontExistProc() will be called and
     * EnumFontFamilies() will return whatever WinFontExistProc() returns. If
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







-
+







    HFONT hFont,		/* HFONT to query. */
    USHORT **startCountPtr,	/* Filled with malloced pointer to character
				 * range information. */
    USHORT **endCountPtr,	/* Filled with malloced pointer to character
				 * range information. */
    int *symbolPtr)
 {
    int n, i, swapped, offset, cbData, segCount;
    int n, i, j, k, swapped, offset, cbData, segCount;
    DWORD cmapKey;
    USHORT *startCount, *endCount;
    CMAPTABLE cmapTable;
    ENCODINGTABLE encTable;
    SUBTABLE subTable;
    char *s;

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
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







-
-
-
+
+
+















-
-
-
-
-
+
+
+
+
+







		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++) {
			SwapShort(&endCount[i]);
			SwapShort(&startCount[i]);
		    for (j = 0; j < segCount; j++) {
			SwapShort(&endCount[j]);
			SwapShort(&startCount[j]);
		    }
		}
		if (*symbolPtr != 0) {
		    /*
		     * Empirically determined: When a symbol font is loaded,
		     * the character existence metrics obtained from the
		     * system are mildly wrong. If the real range of the
		     * symbol font is from 0020 to 00FE, then the metrics are
		     * reported as F020 to F0FE. When we load a symbol font,
		     * we must fix the character existence metrics.
		     *
		     * Symbol fonts should only use the symbol encoding for
		     * 8-bit characters [note Bug: 2406]
		     */

		    for (i = 0; i < segCount; i++) {
			if (((startCount[i] & 0xff00) == 0xf000)
				&& ((endCount[i] & 0xff00) == 0xf000)) {
			    startCount[i] &= 0xff;
			    endCount[i] &= 0xff;
		    for (k = 0; k < segCount; k++) {
			if (((startCount[k] & 0xff00) == 0xf000)
				&& ((endCount[k] & 0xff00) == 0xf000)) {
			    startCount[k] &= 0xff;
			    endCount[k] &= 0xff;
			}
		    }
		}
	    }
	}
    } else if (GetTextCharset(hdc) == ANSI_CHARSET) {
	/*
Changes to win/tkWinImage.c.
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
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));
    XImage* imagePtr = 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;
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325







-















-
+







    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);
    hbmpPrev = SelectObject(hdcMem, hbmp);
    hPal = state.palette;
    if (hPal) {
	hPalPrev1 = SelectPalette(hdcMem, hPal, FALSE);
	n = RealizePalette(hdcMem);
	if (n > 0) {
	    UpdateColors(hdcMem);
	}
350
351
352
353
354
355
356
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

371
372
373
374
375
376
377
378







-
+

















-
+







	depth = twdPtr->bitmap.depth;
    }

    size = sizeof(BITMAPINFO);
    if (depth <= 8) {
	size += sizeof(unsigned short) << depth;
    }
    bmInfo = (BITMAPINFO *)ckalloc(size);
    bmInfo = ckalloc(size);

    bmInfo->bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
    bmInfo->bmiHeader.biWidth		= width;
    bmInfo->bmiHeader.biHeight		= -(int) height;
    bmInfo->bmiHeader.biPlanes		= 1;
    bmInfo->bmiHeader.biBitCount	= depth;
    bmInfo->bmiHeader.biCompression	= BI_RGB;
    bmInfo->bmiHeader.biSizeImage	= 0;
    bmInfo->bmiHeader.biXPelsPerMeter	= 0;
    bmInfo->bmiHeader.biYPelsPerMeter	= 0;
    bmInfo->bmiHeader.biClrUsed		= 0;
    bmInfo->bmiHeader.biClrImportant	= 0;

    if (depth == 1) {
	unsigned char *p, *pend;

	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *)ckalloc(bmInfo->bmiHeader.biSizeImage);
	data = 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);
404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414







-
+







	}
    } else if (depth == 8) {
	unsigned short *palette;
	unsigned int i;
	unsigned char *p;

	GetDIBits(hdcMem, hbmp, 0, height, NULL, bmInfo, DIB_PAL_COLORS);
	data = (unsigned char *)ckalloc(bmInfo->bmiHeader.biSizeImage);
	data = 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);
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445







-
+







	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);
	data = 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 */);
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
457
458
459
460
461
462
463

464
465
466
467
468
469
470
471







-
+







	    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);
	data = 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);
484
485
486
487
488
489
490
491

492
493
494
495
496
497
498
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494







-
+







	     * 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);
	    smallBitBase = ckalloc(byte_width * height);
	    if (!smallBitBase) {
		ckfree(ret_image->data);
		ckfree(ret_image);
		ret_image = NULL;
		goto cleanup;
	    }
	    smallBitData = smallBitBase;
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
581
582
583
584
585
586
587

588
589
590
591
592
593
594
595







-
+







    unsigned long plane_mask,
    int	format)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *)d;
    XImage *imagePtr;
    HDC dc;

    display->request++;
    LastKnownRequestProcessed(display)++;

    if (twdPtr == NULL) {
	/*
	 * Avoid unmapped windows or bad drawables
	 */

	return NULL;
614
615
616
617
618
619
620
621
622


623
624
625
626
627
628
629
610
611
612
613
614
615
616


617
618
619
620
621
622
623
624
625







-
-
+
+







	COLORREF pixel;

	dc = TkWinGetDrawableDC(display, d, &state);

	imagePtr = XCreateImage(display, NULL, 32, format, 0, NULL,
		width, height, 32, 0);
	size = imagePtr->bytes_per_line * imagePtr->height;
	imagePtr->data = (char *)ckalloc(size);
	ZeroMemory(imagePtr->data, size);
	imagePtr->data = ckalloc(size);
	memset(imagePtr->data, 0, size);

	for (yy = 0; yy < height; yy++) {
	    for (xx = 0; xx < width; xx++) {
		pixel = GetPixel(dc, x+(int)xx, y+(int)yy);
		if (pixel == CLR_INVALID) {
		    break;
		}
661
662
663
664
665
666
667
668

669
670
671
672
673
674
675
657
658
659
660
661
662
663

664
665
666
667
668
669
670
671







-
+








	    TkpDisplayWarning(errMsg, "XGetImage Failure");
	    return NULL;
	}

	imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL,
		width, height, 32, 0);
	imagePtr->data = (char *)ckalloc(imagePtr->bytes_per_line * imagePtr->height);
	imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height);

	dc = GetDC(NULL);

	GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL,
		infoPtr, DIB_RGB_COLORS);

	infoPtr->bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
Changes to win/tkWinInit.c.
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
29
30
31
32
33
34
35

36
37

38
39
40
41
42
43
44







-
+

-







 *	Sets "tk_library" Tcl variable, runs "tk.tcl" script.
 *
 *----------------------------------------------------------------------
 */

int
TkpInit(
    Tcl_Interp *interp)
    TCL_UNUSED(Tcl_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;
Changes to win/tkWinInt.h.
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15







-
+







/*
 * tkWinInt.h --
 *
 *	This file contains declarations that are shared among the
 *	Windows-specific parts of Tk, but aren't used by the rest of Tk.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 * 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.
 */

#ifndef _TKWININT
#define _TKWININT
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
138
139
140
141
142
143
144



145
146
147
148
149
150
151







-
-
-








/*
 * 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);

190
191
192
193
194
195
196
197
198
199
200
201
202






203
204
205


206
207
208
209
210
211
212
213
214
215








216
217
218
219
220

221
222
223
224
225
226
227
187
188
189
190
191
192
193






194
195
196
197
198
199
200


201
202




203
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 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,
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 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);
MODULE_SCOPE void	TkSetCursorPos(int x, int y);

/*
 * The following is implemented in tkWinDraw.c and used in tkUtil.c
 */

MODULE_SCOPE  void	TkWinDrawDottedRect(Display *disp, Drawable d,
			    long pixel, int x, int y, int width, int height);

/*
 * Common routines used in Windows implementation
 */
MODULE_SCOPE Tcl_Obj *	        TkWin32ErrorObj(HRESULT hrError);
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.
 */
245
246
247
248
249
250
251





252

253
254
255
256
245
246
247
248
249
250
251
252
253
254
255
256

257

258
259
260







+
+
+
+
+
-
+
-



#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 */

/*
 * MSVC versions before 2015 don't know snprintf, but _snprintf is compatible.
 * Note that sprintf is deprecated.
 */
#if defined(_MSC_VER) && _MSC_VER < 1900
#ifdef __cplusplus
#    define snprintf _snprintf
}
#endif

#endif /* _TKWININT */
Changes to win/tkWinKey.c.
86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108







-
+








-







 *	None.
 *
 *----------------------------------------------------------------------
 */

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred: needed to get
    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. */
{
    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);
148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
147
148
149
150
151
152
153

154
155
156
157
158


















159
160
161
162
163
164
165







-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XKeycodeToKeysym(
    Display *display,
    TCL_UNUSED(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);
}

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
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







-
+





-
+






-







	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
 * 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,
    TCL_UNUSED(Tk_Window),
    KeySym keySym,
    XEvent *eventPtr)
{
    int i;
    SHORT result;
    int shift;
    (void)tkwin;

    eventPtr->xkey.keycode = 0;
    if (keySym == NoSymbol) {
	return;
    }

    /*
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
603
604
605
606
607
608
609

610
611
612
613
614

615
616
617
618
619
620
621







-
+




-







 *	None.
 *
 *----------------------------------------------------------------------
 */

KeyCode
XKeysymToKeycode(
    Display *display,
    TCL_UNUSED(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.
     */

672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
687
688
689
651
652
653
654
655
656
657

658
659
660

661
662
663
664
665
666
667







-
+


-







 *	Allocates a new modifier map data structure.
 *
 *----------------------------------------------------------------------
 */

XModifierKeymap	*
XGetModifierMapping(
    Display *display)
    TCL_UNUSED(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;
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
751
712
713
714
715
716
717
718

719
720


721
722
723
724
725
726
727







-
+

-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

KeySym
XStringToKeysym(
    _Xconst char *string)
    TCL_UNUSED(_Xconst char *))
{
    (void)string;

    return NoSymbol;
}

/*
 *----------------------------------------------------------------------
 *
 * XKeysymToString --
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
735
736
737
738
739
740
741

742
743


744
745
746
747
748
749
750
751
752
753







-
+

-
-










 *	None.
 *
 *----------------------------------------------------------------------
 */

char *
XKeysymToString(
    KeySym keysym)
    TCL_UNUSED(KeySym))
{
    (void)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
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15






-
-
+
+







/*
 * 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.
 * Copyright (c) 1996-1998 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#define OEMRESOURCE
#include "tkWinInt.h"
172
173
174
175
176
177
178
179

180
181
182
183

184
185
186
187
188
189
190
172
173
174
175
176
177
178

179


180

181
182
183
184
185
186
187
188







-
+
-
-

-
+







			    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);
static int		GetNewID(TkMenuEntry *mePtr, WORD *menuIDPtr);
static int		TkWinMenuKeyObjCmd(ClientData clientData,
static Tcl_ObjCmdProc TkWinMenuKeyObjCmd;
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		MenuSelectEvent(TkMenu *menuPtr);
static void		ReconfigureWindowsMenu(ClientData clientData);
static void		ReconfigureWindowsMenu(void *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);

329
330
331
332
333
334
335
336

337
338
339

340
341
342
343
344
345
346
327
328
329
330
331
332
333

334
335
336

337
338
339
340
341
342
343
344







-
+


-
+







    Tcl_HashEntry *hashEntryPtr;
    int newEntry;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    winMenuHdl = CreatePopupMenu();
    if (winMenuHdl == NULL) {
    	Tcl_SetObjResult(menuPtr->interp, Tcl_NewStringObj(
	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;
	return TCL_ERROR;
    }

    /*
     * We hash all of the HMENU's so that we can get their menu ptrs back when
     * dispatch messages.
     */

422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434







-
+







	    Tcl_HashEntry *hashEntryPtr =
		Tcl_FindHashEntry(&tsdPtr->winMenuTable, winMenuHdl);

	    if (hashEntryPtr != NULL) {
		Tcl_DeleteHashEntry(hashEntryPtr);
	    }
	}
 	DestroyMenu(winMenuHdl);
	DestroyMenu(winMenuHdl);
    }
    menuPtr->platformData = NULL;

    if (menuPtr == tsdPtr->modalMenuPtr) {
	tsdPtr->modalMenuPtr = NULL;
    }
}
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
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







-
+


-
-
+
+












-
+


+






-
+







	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;
	Tcl_UniChar ch = 0;

	/*
	 * We have to construct the string with an ampersand preceeding the
	 * underline character, and a tab seperating the text and the accel
	 * We have to construct the string with an ampersand preceding the
	 * underline character, and a tab separating 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);
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    Tcl_DStringAppend(&itemString, p, (int) (next - p));
	}
	ch = 0;
	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);
		next = p + Tcl_UtfToUniChar(p, &ch);
		Tcl_DStringAppend(&itemString, p, (int) (next - p));
	    }
	}

	itemText = (char *)ckalloc(Tcl_DStringLength(&itemString) + 1);
	strcpy(itemText, Tcl_DStringValue(&itemString));
	Tcl_DStringFree(&itemString);
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590







-
+







    LPCWSTR lpNewItem;
    UINT flags;
    UINT itemID;
    int i, count, systemMenu = 0, base;
    Tcl_DString translatedText;

    if (NULL == winMenuHdl) {
    	return;
	return;
    }

    /*
     * Reconstruct the entire menu. Takes care of nasty system menu and index
     * problem.
     */

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
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







-
+










-
+







			    & 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);
			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->mainMenuPtr
			&& (systemMenuPtr->masterMenuPtr
				== menuRefPtr->menuPtr)) {
		    HMENU systemMenuHdl = (HMENU) systemMenuPtr->platformData;
		    HWND wrapper = TkWinGetWrapperWindow(menuPtr
			    ->parentTopLevelPtr);

		    if (wrapper != NULL) {
			DestroyMenu(systemMenuHdl);
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
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







-
+











-










-
+













-
+







 *	The menu is posted and handled.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostMenu(
    Tcl_Interp *dummy,
    TCL_UNUSED(Tcl_Interp *),
    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) {
    if (index >= 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--;
    	return TCL_OK;
	return TCL_OK;
    }

    if (NULL == parentWindow) {
	noGoawayRect.top = y - 50;
	noGoawayRect.bottom = y + 50;
	noGoawayRect.left = x - 50;
	noGoawayRect.right = x + 50;
838
839
840
841
842
843
844
845

846
847
848
849
850
851
852
836
837
838
839
840
841
842

843
844
845
846
847
848
849
850







-
+







    }

    TrackPopupMenu(winMenuHdl, flags, x, y, 0,
	    tsdPtr->menuHWND, &noGoawayRect);
    Tcl_SetServiceMode(oldServiceMode);

    GetCursorPos(&point);
    TkWinPointerEvent(NULL, point.x, point.y);
    Tk_PointerEvent(NULL, point.x, point.y);

    if (tsdPtr->inPostMenu) {
	tsdPtr->inPostMenu = 0;
    }
    return TCL_OK;
}

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
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







-
+






-
-
-
-
-
-
-
-





-
+








-
+


-
+
+
+
+
+
+
+
+
+
+
+
+
+







 *	The menu is posted.
 *
 *----------------------------------------------------------------------
 */

int
TkpPostTearoffMenu(
    Tcl_Interp *dummy,		/* The interpreter of the menu */
    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 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;
	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;
	return TCL_OK;
    }

    /*
     /*
     * Adjust the menu y position so that the specified entry will be located
     * at the given coordinates.
     */

    if (index >= menuPtr->numEntries) {
	index = menuPtr->numEntries - 1;
    }
    if (index >= 0) {
	y -= menuPtr->entries[index]->y;
    }

   /*
     * Adjust the position of the menu if necessary to keep it visible on the
     * screen. There are two special tricks to make this work right:
     *
     * 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
967
968
969
970
971
972
973
974

975
976
977
978
979
980
981
969
970
971
972
973
974
975

976
977
978
979
980
981
982
983







-
+







TkpMenuNewEntry(
    TkMenuEntry *mePtr)
{
    WORD commandID;
    TkMenu *menuPtr = mePtr->menuPtr;

    if (GetNewID(mePtr, &commandID) != TCL_OK) {
    	return TCL_ERROR;
	return TCL_ERROR;
    }
    ScheduleMenuReconfigure(menuPtr);
    mePtr->platformEntryData = (TkMenuPlatformEntryData) INT2PTR(commandID);

    return TCL_OK;
}

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
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







-
+











-







 *	should be returned to windows from this message.
 *
 *----------------------------------------------------------------------
 */

int
TkWinHandleMenuEvent(
    HWND *phwnd,
    TCL_UNUSED(HWND *),
    UINT *pMessage,
    WPARAM *pwParam,
    LPARAM *plParam,
    LRESULT *plResult)
{
    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);
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
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







+





+










-
+







		    TkActivateMenuEntry(parentEntryPtr->menuPtr,
			    parentEntryPtr->index);
		}
	    }

	    interp = menuPtr->interp;
	    Tcl_Preserve(interp);
	    Tcl_Preserve(menuPtr);
	    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(menuPtr);
	    Tcl_Release(interp);
	    *plResult = 0;
	    returnResult = 1;
	}
	break;

    case WM_MENUCHAR: {
	hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable,
		*plParam);
	if (hashEntryPtr != NULL) {
	    TkSizeT i, len;
	    int i, len;
	    int underline;
	    Tcl_Obj *labelPtr;
	    WCHAR *wlabel;
	    int menuChar;
	    Tcl_DString ds;

	    *plResult = 0;
1271
1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1274
1275
1276
1277
1278
1279
1280

1281
1282
1283
1284
1285

1286
1287
1288
1289
1290
1291
1292
1293







-
+




-
+







	    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);
		    const char *src = Tcl_GetStringFromObj(labelPtr, &len);

		    Tcl_DStringFree(&ds);
		    Tcl_DStringInit(&ds);
		    wlabel = Tcl_UtfToWCharDString(src, len, &ds);
		    if (((TkSizeT)underline + 1 < len + 1) && (menuChar ==
		    if ((underline < len) && (menuChar ==
				Tcl_UniCharToUpper(wlabel[underline]))) {
			*plResult = (2 << 16) | i;
			returnResult = 1;
			break;
		    }
		}
	    }
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
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







-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
+
+
+

-
+













-
+







		    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.
                     */
		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;
		    entryIndex++;
		}
		mePtr = NULL;
		if (flags != 0xFFFF) {
		    if ((flags&MF_POPUP) && (entryIndex < (int)menuPtr->numEntries)) {
		    if ((flags&MF_POPUP) && (entryIndex < 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) {
		    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;
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
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







-
+





-
+




-
-
-
-
-
-
+
+
+
+
+
+







 *----------------------------------------------------------------------
 */

void
RecursivelyClearActiveMenu(
    TkMenu *menuPtr)		/* The menu to reset. */
{
    TkSizeT i;
    int i;
    TkMenuEntry *mePtr;

    TkActivateMenuEntry(menuPtr, -1);
    MenuSelectEvent(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	mePtr = menuPtr->entries[i];
	mePtr = menuPtr->entries[i];
	if (mePtr->state == ENTRY_ACTIVE) {
	    mePtr->state = ENTRY_NORMAL;
	}
	mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1;
    	if (mePtr->type == CASCADE_ENTRY) {
    	    if ((mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
    	    	RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr);
    	    }
    	}
	if (mePtr->type == CASCADE_ENTRY) {
	    if ((mePtr->childMenuRefPtr != NULL)
		    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr);
	    }
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpSetWindowMenuBar --
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561




1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1554
1555
1556
1557
1558
1559
1560




1561
1562
1563
1564
1565




1566
1567
1568
1569
1570
1571
1572







-
-
-
-
+
+
+
+

-
-
-
-







 *	The menubar is 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. If
    				 * NULL, use the default menu bar. */
    TCL_UNUSED(Tcl_Interp *),		/* The interpreter of the application */
    TCL_UNUSED(Tk_Window),		/* The frame we are setting up */
    TCL_UNUSED(const char *))	/* 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.
     */
}

/*
 *----------------------------------------------------------------------
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
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







-
-
+
+



-
-
-
-










-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+







 *----------------------------------------------------------------------
 */

void
GetMenuIndicatorGeometry(
    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 */
    TCL_UNUSED(Tk_Font),		/* Precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* 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;
        }
	/*
	 * 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 --
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
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







-
-
-
-
-
-
+
+
+
+
+
+






-
+







    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.
         */
	/*
	 * 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;
	*widthPtr = 0;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * GetTearoffEntryGeometry --
1677
1678
1679
1680
1681
1682
1683
1684
1685


1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1672
1673
1674
1675
1676
1677
1678


1679
1680
1681
1682
1683
1684



1685
1686
1687
1688
1689
1690
1691







-
-
+
+




-
-
-







 *
 *----------------------------------------------------------------------
 */

void
GetTearoffEntryGeometry(
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are measuring */
    TCL_UNUSED(Tk_Font),		/* 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;
}
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
1704
1705
1706
1707
1708
1709
1710



1711
1712
1713
1714
1715
1716
1717




1718
1719
1720
1721
1722
1723
1724







-
-
-
+
+
+




-
-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
GetMenuSeparatorGeometry(
    TkMenu *menuPtr,		/* The menu we are measuring */
    TkMenuEntry *mePtr,		/* The entry we are measuring */
    Tk_Font tkfont,		/* The precalculated font */
    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 */
{
    (void)menuPtr;
    (void)mePtr;
    (void)tkfont;

    *widthPtr = 0;
    *heightPtr = fmPtr->linespace - (2 * fmPtr->descent);
}

/*
 *----------------------------------------------------------------------
 *
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
1817
1818
1819
1820
1821
1822
1823


1824
1825
1826
1827


1828
1829
1830





1831
1832

1833
1834
1835
1836
1837
1838
1839
1840







-
-
+
+


-
-
+
+

-
-
-
-
-


-
+







void
DrawMenuEntryIndicator(
    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 with */
    GC indicatorGC,		/* The gc for indicator objects */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* The precalculated font metrics */
    int x,			/* Left edge */
    int y,			/* Top edge */
    int width,
    int height)
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    (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)) {
	if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) {
	    RECT rect;
	    GC whichGC;
	    int borderWidth, activeBorderWidth;

	    if (mePtr->state != ENTRY_NORMAL) {
		whichGC = gc;
	    } else {
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
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







-
+


-
+





-
-
-


-
+







DrawMenuEntryAccelerator(
    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 with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    Tk_3DBorder activeBorder,	/* The border when an item is active */
    TCL_UNUSED(Tk_3DBorder),	/* The border when an item is active */
    int x,			/* left edge */
    int y,			/* top edge */
    int width,			/* Width of menu entry */
    TCL_UNUSED(int),			/* 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;
	return;
    }

    if (mePtr->accelPtr != NULL) {
	accel = Tcl_GetString(mePtr->accelPtr);
    } else {
	accel = NULL;
    }
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
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







-
+











-
-











-
-
+
+








void
DrawMenuEntryArrow(
    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 with */
    Tk_3DBorder activeBorder,	/* The border when an item is active */
    TCL_UNUSED(Tk_3DBorder),	/* 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;
	   || (mePtr->childMenuRefPtr->menuPtr == NULL)) {
	return;
    }

    oldFgColor = gc->foreground;
    oldBgColor = gc->background;

    /*
     * Set bitmap bg to highlight color if the menu is highlighted.
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
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







-
+

-
-
-
+
+
+







-
-
-
-







 *
 *----------------------------------------------------------------------
 */

void
DrawMenuSeparator(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* The entry we are drawing */
    Drawable d,			/* What we are drawing into */
    GC gc,			/* The gc we are drawing with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated font metrics */
    TCL_UNUSED(GC),			/* The gc we are drawing with */
    TCL_UNUSED(Tk_Font),		/* The precalculated font */
    TCL_UNUSED(const Tk_FontMetrics *),/* The precalculated font metrics */
    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,
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
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







-
+


-
-
-






-
+


-
+

+
+

-
+







    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,			/* Left Edge */
    int y,			/* Top Edge */
    int width,			/* Width of entry */
    TCL_UNUSED(int),			/* 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;
	    int activeBorderWidth, ch;

	    label = Tcl_GetString(mePtr->labelPtr);
	    start = Tcl_UtfAtIndex(label, mePtr->underline);
	    start = TkUtfAtIndex(label, mePtr->underline);
	    end = start + TkUtfToUniChar(start, &ch);
	    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
		    menuPtr->activeBorderWidthPtr, &activeBorderWidth);
	    Tk_UnderlineChars(menuPtr->display, d,
		    gc, tkfont, label, x + mePtr->indicatorSpace,
		    gc, tkfont, label, x + mePtr->indicatorSpace + activeBorderWidth,
		    y + (height + fmPtr->ascent - fmPtr->descent) / 2,
		    (int) (start - label), (int) (end - label));
	}
    }
}

/*
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
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







-
+











-







 *	The menu system may take over and process user events for menu input.
 *
 *--------------------------------------------------------------
 */

static int
TkWinMenuKeyObjCmd(
    ClientData dummy,	/* Unused. */
    TCL_UNUSED(void *),
    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]),
2325
2326
2327
2328
2329
2330
2331
2332

2333
2334
2335
2336
2337
2338

2339
2340
2341
2342
2343
2344
2345
2297
2298
2299
2300
2301
2302
2303

2304
2305
2306
2307
2308
2309

2310
2311
2312
2313
2314
2315
2316
2317







-
+





-
+







    (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);
	    "<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,
	    "<Key-F10>", "tk::WinMenuKey %W %N", 0);
	    "<KeyPress-F10>", "tk::WinMenuKey %W %N", 0);

    (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid,
	    "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0);
}

/*
 *----------------------------------------------------------------------
2386
2387
2388
2389
2390
2391
2392
2393

2394
2395
2396
2397
2398
2399
2400
2358
2359
2360
2361
2362
2363
2364

2365
2366
2367
2368
2369
2370
2371
2372







-
+







    leftEdge = x + indicatorSpace + activeBorderWidth;

    /*
     * Work out what we will need to draw first.
     */

    if (mePtr->image != NULL) {
    	Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight);
	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;
    }
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
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







-
-
+
+



-
+



-
+


-
+





-
+







    }

    /*
     * Draw label and/or bitmap or image for entry.
     */

    if (mePtr->image != NULL) {
    	if ((mePtr->selectImage != NULL)
	    	&& (mePtr->entryFlags & ENTRY_SELECTED)) {
	if ((mePtr->selectImage != NULL)
		&& (mePtr->entryFlags & ENTRY_SELECTED)) {
	    Tk_RedrawImage(mePtr->selectImage, 0, 0,
		    imageWidth, imageHeight, d, leftEdge + imageXOffset,
		    (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset));
    	} else {
	} 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,
	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) {
    	if (mePtr->labelLength > 0) {
	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,
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
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







-
+

-
-
-
+
+
+






-
-
-
-







 *
 *----------------------------------------------------------------------
 */

void
DrawTearoffEntry(
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    TCL_UNUSED(TkMenuEntry *),		/* 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 */
    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;
    (void)mePtr;
    (void)gc;
    (void)tkfont;
    (void)fmPtr;

    if (menuPtr->menuType != MAIN_MENU) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
2701
2702
2703
2704
2705
2706
2707
2708

2709
2710
2711
2712
2713
2714
2715
2669
2670
2671
2672
2673
2674
2675

2676
2677
2678
2679
2680
2681
2682
2683







-
+







     */

    if (mePtr->image != NULL) {
	menuDc = TkWinGetDrawableDC(menuPtr->display, menuDrawable, &dcState);

	memDc = CreateCompatibleDC(menuDc);
	oldBitmap = (HBITMAP)SelectObject(memDc,
    			CreateCompatibleBitmap(menuDc, width, height) );
			CreateCompatibleBitmap(menuDc, width, height) );

	memWinDraw.type = TWD_WINDC;
	memWinDraw.winDC.hdc = memDc;
	d = (Drawable)&memWinDraw;
	adjustedX = 0;
	adjustedY = padY;

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
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







-
-
-
+
+
+

-
-
-
+
+
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+








    if ((mePtr->state == ENTRY_ACTIVE) && !strictMotif) {
	gc = mePtr->activeGC;
	if (gc == NULL) {
	    gc = menuPtr->activeGC;
	}
    } else {
    	TkMenuEntry *cascadeEntryPtr;
    	int parentDisabled = 0;
    	const char *name;
	TkMenuEntry *cascadeEntryPtr;
	int parentDisabled = 0;
	const char *name;

    	for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;
    		cascadeEntryPtr != NULL;
    		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {
	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) {
    	    	    parentDisabled = 1;
    	    	}
    	    	break;
    	    }
    	}
	    if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) {
		if (mePtr->state == ENTRY_DISABLED) {
		    parentDisabled = 1;
		}
		break;
	    }
	}

	if (((parentDisabled || (mePtr->state == ENTRY_DISABLED)))
		&& (menuPtr->disabledFgPtr != NULL)) {
	    gc = mePtr->disabledGC;
	    if (gc == NULL) {
		gc = menuPtr->disabledGC;
	    }
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
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







-
+




-
+















-
+







    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);
	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);
	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) {
	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) {
2929
2930
2931
2932
2933
2934
2935
2936

2937
2938
2939
2940
2941
2942
2943
2897
2898
2899
2900
2901
2902
2903

2904
2905
2906
2907
2908
2909
2910
2911







-
+







	    }
	} else {
	    /*
	     * An empty entry still has this height.
	     */

	    *heightPtr = fmPtr->linespace;
    	}
	}
    }
    *heightPtr += 1;
}

/*
 *----------------------------------------------------------------------
 *
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
2932
2933
2934
2935
2936
2937
2938



2939

2940














2941
2942

2943
2944
2945
2946
2947
2948
2949







-
-
-

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-







    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);
    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
3056
3057



3058
3059
3060
3061
3062
3063
3064
2993
2994
2995
2996
2997
2998
2999

3000
3001
3002
3003
3004
3005
3006



3007
3008
3009
3010
3011
3012
3013
3014
3015
3016







-
+






-
-
-
+
+
+








    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++) {
    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);
    	    fmPtr = &entryMetrics;
    	}
	    Tk_GetFontMetrics(tkfont, &entryMetrics);
	    fmPtr = &entryMetrics;
	}
	if ((i > 0) && menuPtr->entries[i]->columnBreak) {
	    if (accelWidth != 0) {
		labelWidth += accelSpace;
	    }
	    for (j = lastColumnBreak; j < i; j++) {
		menuPtr->entries[j]->indicatorSpace = indicatorSpace;
		menuPtr->entries[j]->labelWidth = labelWidth;
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
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







-
+



-
+












-
+


-
+





-
+


-
+



-
+

-
+


-
+



-
+










-
+







	    indicatorSpace = labelWidth = accelWidth = 0;
	    lastColumnBreak = i;
	    y = borderWidth;
	}

	if (menuPtr->entries[i]->type == SEPARATOR_ENTRY) {
	    GetMenuSeparatorGeometry(menuPtr, menuPtr->entries[i], tkfont,
	    	    fmPtr, &width, &height);
		    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);
		    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,
	     * on the type of the entry.
	     */

	    GetMenuLabelGeometry(menuPtr->entries[i], tkfont, fmPtr, &width,
	    	    &height);
		    &height);
	    menuPtr->entries[i]->height = height;
	    if (width > labelWidth) {
	    	labelWidth = width;
		labelWidth = width;
	    }

	    GetMenuAccelGeometry(menuPtr, menuPtr->entries[i], tkfont,
		    fmPtr, &width, &height);
	    if (height > menuPtr->entries[i]->height) {
	    	menuPtr->entries[i]->height = height;
		menuPtr->entries[i]->height = height;
	    }
	    if (width > accelWidth) {
	    	accelWidth = width;
		accelWidth = width;
	    }

	    GetMenuIndicatorGeometry(menuPtr, menuPtr->entries[i], tkfont,
	    	    fmPtr, &width, &height);
		    fmPtr, &width, &height);
	    if (height > menuPtr->entries[i]->height) {
	    	menuPtr->entries[i]->height = height;
		menuPtr->entries[i]->height = height;
	    }
	    if (width > indicatorSpace) {
	    	indicatorSpace = width;
		indicatorSpace = width;
	    }

	    menuPtr->entries[i]->height += 2 * activeBorderWidth + 1;
    	}
	}
	menuPtr->entries[i]->y = y;
	y += menuPtr->entries[i]->height;
	if (y > windowHeight) {
	    windowHeight = y;
	}
    }

    if (accelWidth != 0) {
	labelWidth += accelSpace;
    }
    for (j = lastColumnBreak; j < (int)menuPtr->numEntries; j++) {
    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;
    }
3178
3179
3180
3181
3182
3183
3184
3185

3186
3187
3188
3189
3190
3191
3192
3130
3131
3132
3133
3134
3135
3136

3137
3138
3139
3140
3141
3142
3143
3144







-
+







    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.serial = LastKnownRequestProcessed(menuPtr->display);
    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();
3226
3227
3228
3229
3230
3231
3232
3233

3234
3235
3236
3237
3238
3239
3240
3178
3179
3180
3181
3182
3183
3184

3185
3186
3187
3188
3189
3190
3191
3192







-
+







{
    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;
	    for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL;
		    menuPtr = menuPtr->nextInstancePtr) {
		if (menuPtr->menuType == MENUBAR) {
		    ScheduleMenuReconfigure(menuPtr);
		}
	    }
	}
    }
3257
3258
3259
3260
3261
3262
3263
3264

3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3209
3210
3211
3212
3213
3214
3215

3216
3217
3218
3219

3220
3221
3222
3223
3224
3225
3226







-
+



-







 *	None.
 *
 *----------------------------------------------------------------------
 */

HWND
Tk_GetMenuHWND(
    Tk_Window tkwin)
    TCL_UNUSED(Tk_Window))
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    (void)tkwin;

    TkMenuInit();
    return tsdPtr->embeddedMenuHWND;
}

/*
 *----------------------------------------------------------------------
3285
3286
3287
3288
3289
3290
3291
3292

3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3236
3237
3238
3239
3240
3241
3242

3243
3244


3245
3246
3247
3248
3249
3250
3251







-
+

-
-







 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuExitHandler(
    ClientData dummy)	    /* Not used */
    TCL_UNUSED(void *))	    /* Not used */
{
    (void)dummy;

    UnregisterClassW(MENU_CLASS_NAME, Tk_GetHINSTANCE());
    UnregisterClassW(EMBEDDED_MENU_CLASS_NAME, Tk_GetHINSTANCE());
}

/*
 *----------------------------------------------------------------------
 *
3312
3313
3314
3315
3316
3317
3318
3319

3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3261
3262
3263
3264
3265
3266
3267

3268
3269
3270
3271

3272
3273
3274
3275
3276
3277
3278







-
+



-







 *	Menus have to be reinitialized next time.
 *
 *----------------------------------------------------------------------
 */

static void
MenuThreadExitHandler(
    ClientData dummy)	    /* Not used */
    TCL_UNUSED(void *))
{
    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);
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
3296
3297
3298
3299
3300
3301
3302

3303
3304

3305
3306
3307


3308
3309
3310

3311
3312
3313
3314
3315
3316
3317
3318







-
+

-
+


-
-



-
+







 *	Storage is allocated.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkWinGetMenuSystemDefault(
    Tk_Window tkwin,		/* A window to use. */
    TCL_UNUSED(Tk_Window),		/* A window to use. */
    const char *dbName,		/* The option database name. */
    const char *className)	/* The name of the option class. */
    TCL_UNUSED(const char *))	/* 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);
	valuePtr = Tcl_NewIntObj(defaultBorderWidth);
    } else if (strcmp(dbName, "font") == 0) {
	valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), -1);
    }

    return valuePtr;
}

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
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







+
-
+
+
+
+
+

















-
+


-
+


-
-
-
+
+
+


















-
+







    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 */
    struct {
    NONCLIENTMETRICSW metrics;
	NONCLIENTMETRICSW metrics;
#if (WINVER < 0x0600)
	int padding;
#endif
    } nc;

    /*
     * 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);
    nc.metrics.cbSize = sizeof(nc);

    if (TkWinGetPlatformTheme() != TK_THEME_WIN_VISTA) {
	metrics.cbSize -= sizeof(int);
	nc.metrics.cbSize -= sizeof(int);
    }

    SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, metrics.cbSize,
	    &metrics, 0);
    menuFont = CreateFontIndirectW(&metrics.lfMenuFont);
    SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, nc.metrics.cbSize,
	    &nc.metrics, 0);
    menuFont = CreateFontIndirectW(&nc.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;
    }

    SelectObject(scratchDC, GetStockObject(SYSTEM_FONT));
    DeleteDC(scratchDC);

    DeleteObject(menuFont);

    Tcl_DStringAppendElement(&menuFontDString, faceName);
    sprintf(sizeString, "%d", pointSize);
    snprintf(sizeString, sizeof(sizeString), "%d", pointSize);
    Tcl_DStringAppendElement(&menuFontDString, sizeString);

    if (bold || italic) {
	Tcl_DString boldItalicDString;

	Tcl_DStringInit(&boldItalicDString);
	if (bold) {
Changes to win/tkWinPixmap.c.
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61

62
63
64
65
66
67
68
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60

61
62
63
64
65
66
67
68







-
+















-
+

-
+







    int height,
    int depth)
{
    TkWinDrawable *newTwdPtr, *twdPtr;
    int planes;
    Screen *screen;

    display->request++;
    LastKnownRequestProcessed(display)++;

    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));
	} else {
	    newTwdPtr->bitmap.colormap = twdPtr->window.winPtr->atts.colormap;
	}
    } else {
	newTwdPtr->bitmap.colormap = twdPtr->bitmap.colormap;
    }
    screen = &display->screens[0];
    screen = ScreenOfDisplay(display, 0);
    planes = 1;
    if (depth == screen->root_depth) {
    if (depth == DefaultDepthOfScreen(screen)) {
	planes = PTR2INT(screen->ext_data);
	depth /= planes;
    }
    newTwdPtr->bitmap.handle =
	    CreateBitmap(width, height, (DWORD) planes, (DWORD) depth, NULL);

    /*
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154







-
+







void
Tk_FreePixmap(
    Display *display,
    Pixmap pixmap)
{
    TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;

    display->request++;
    LastKnownRequestProcessed(display)++;
    if (twdPtr != NULL) {
	DeleteObject(twdPtr->bitmap.handle);
	ckfree(twdPtr);
    }
}

/*
193
194
195
196
197
198
199
200

201
202
203
204



205
206
207
208


209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
193
194
195
196
197
198
199

200
201



202
203
204
205
206


207
208
209
210






211
212
213
214
215
216
217







-
+

-
-
-
+
+
+


-
-
+
+


-
-
-
-
-
-







 *	None.
 *
 *----------------------------------------------------------------------
 */

int
XGetGeometry(
    Display *display,
    TCL_UNUSED(Display *),
    Drawable d,
    Window *root_return,
    int *x_return,
    int *y_return,
    TCL_UNUSED(Window *),
    TCL_UNUSED(int *),
    TCL_UNUSED(int *),
    unsigned int *width_return,
    unsigned int *height_return,
    unsigned int *border_width_return,
    unsigned int *depth_return)
    TCL_UNUSED(unsigned int *),
    TCL_UNUSED(unsigned int *))
{
    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");
Changes to win/tkWinPointer.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkWinPointer.c --
 *
 *	Windows specific mouse tracking code.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * 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 "tkWinInt.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
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119







-
+















-
+







    }
    return state;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinPointerEvent --
 * 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
TkWinPointerEvent(
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
175
176
177
178
179
180
181






182
183
184
185
186
187
188







-
-
-
-
-
-







    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;
}

/*
 *----------------------------------------------------------------------
 *
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
200
201
202
203
204
205
206



207
208
209
210
211
212
213







-
-
-







 */

int
XUngrabKeyboard(
    Display *display,
    Time time)
{
    (void)display;
    (void)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
222
223
224
225
226
227
228

229
230
231

232
233
234





235

236
237
238
239
240
241
242
243







-
+


-



-
-
-
-
-

-
+







 *	May schedule a new timer and/or generate enter/leave events.
 *
 *----------------------------------------------------------------------
 */

void
MouseTimerProc(
    ClientData dummy)
    ClientData clientData)
{
    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);
    Tk_PointerEvent(NULL, pos.x, pos.y);
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinCancelMouseTimer --
 *
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
281
282
283
284
285
286
287

288
289
290
291
292
293
294







-







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;
}

/*
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
318
319
320
321
322
323
324






325

326
327
328
329
330
331
332







-
-
-
-
-
-
+
-







    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;

    LastKnownRequestProcessed(display)++;
    display->request++;
    TkGetPointerCoords(NULL, root_x_return, root_y_return);
    *mask_return = TkWinGetModifierState();
    return True;
}

/*
 *----------------------------------------------------------------------
377
378
379
380
381
382
383











384
385
386
387
388
389
390
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379







+
+
+
+
+
+
+
+
+
+
+







void TkSetCursorPos(
    int x,
    int y)
{
    INPUT input;
    int xscreen = (int)(GetSystemMetrics(SM_CXSCREEN) - 1);
    int yscreen = (int)(GetSystemMetrics(SM_CYSCREEN) - 1);

    /*
     * A multi-screen system may have different logical pixels/inch, with
     * Windows applying behind-the-scenes scaling on secondary screens.
     * Don't try and emulate that, instead fall back to SetCursor if the
     * requested position is off the primary screen.
     */
    if ( x < 0 || x > xscreen || y < 0 || y > yscreen ) {
        SetCursorPos(x, y);
        return;
    }

    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
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
403
404
405
406
407
408
409






410
411
412
413
414
415
416







-
-
-
-
-
-







    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
464
465
466
467
468
469
470
471

472
473

474
475
476
477
478
479
480
447
448
449
450
451
452
453

454
455

456
457
458
459
460
461
462
463







-
+

-
+







XGetInputFocus(
    Display *display,
    Window *focus_return,
    int *revert_to_return)
{
    Tk_Window tkwin = Tk_HWNDToWindow(GetFocus());

    *focus_return = tkwin ? Tk_WindowId(tkwin) : 0;
    *focus_return = tkwin ? Tk_WindowId(tkwin) : None;
    *revert_to_return = RevertToParent;
    display->request++;
    LastKnownRequestProcessed(display)++;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XSetInputFocus --
494
495
496
497
498
499
500
501
502
503

504
505
506
507
508
509
510
511
477
478
479
480
481
482
483



484

485
486
487
488
489
490
491







-
-
-
+
-







int
XSetInputFocus(
    Display *display,
    Window focus,
    int revert_to,
    Time time)
{
    (void)revert_to;
    (void)time;

    LastKnownRequestProcessed(display)++;
    display->request++;
    if (focus != None) {
	SetFocus(Tk_GetHWND(focus));
    }
    return Success;
}

/*
Changes to win/tkWinPort.h.
91
92
93
94
95
96
97

98
99
100
101
102
103
104
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







+








#define REDO_KEYSYM_LOOKUP

/*
 * See ticket [916c1095438eae56]: GetVersionExW triggers warnings
 */
#if defined(_MSC_VER)
#   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)
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
121
122
123
124
125
126
127






128
129
130
131
132
133
134
135
136
137







-
-
-
-
-
-










/*
 * 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 */
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
1
2
3
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.
272
273
274
275
276
277
278
























279
280
281
282
283
284
285
286
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








    TkRegion sra,
    TkRegion srb,
    TkRegion dr_return)
{
    CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCopyRegion --
 *
 *  Makes the destination region a copy of the source region.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpCopyRegion(
    TkRegion dst,
    TkRegion src)
{
    CombineRgn((HRGN)dst, (HRGN)src, NULL, RGN_COPY);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to win/tkWinScrlbr.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







/*
 * tkWinScrollbar.c --
 *
 *	This file implements the Windows specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * 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.
 */

#include "tkWinInt.h"
#include "tkScrollbar.h"
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370







-
+







    int arrowWidth = GetSystemMetrics(SM_CXVSCROLL);

    hArrowWidth = GetSystemMetrics(SM_CXHSCROLL);
    hThumb = GetSystemMetrics(SM_CXHTHUMB);
    vArrowHeight = GetSystemMetrics(SM_CYVSCROLL);
    vThumb = GetSystemMetrics(SM_CYVTHUMB);

    sprintf(tkDefScrollbarWidth, "%d", arrowWidth);
    snprintf(tkDefScrollbarWidth, sizeof(tkDefScrollbarWidth), "%d", arrowWidth);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpComputeScrollbarGeometry --
 *
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
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,
	Tk_TranslateWinEvent(NULL, WM_MOUSEMOVE, 0,
		MAKELPARAM(point.x, point.y), &result);

	if (command == SB_ENDSCROLL) {
	    return 0;
	}

	/*
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574







-
+







	Tcl_DStringFree(&cmdString);

	Tcl_ServiceAll();
	return 0;
    }

    default:
	if (TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	    return result;
	}
    }
    return CallWindowProcW(scrollPtr->oldProc, hwnd, message, wParam, lParam);
}

/*
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602
603
604
605
587
588
589
590
591
592
593

594
595
596
597

598
599
600
601
602
603
604







-
+



-







 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
    TkScrollbar *scrollPtr)
    TCL_UNUSED(TkScrollbar *))
				/* Information about widget; may or may not
				 * already have values for some fields. */
{
    (void)scrollPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * ModalLoop --
 *
Changes to win/tkWinSend.c.
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23






-
+








+







/*
 * tkWinSend.c --
 *
 *	This file provides functions that implement the "send" command,
 *	allowing commands to be passed from interpreter to interpreter.
 *
 * Copyright (c) 1997 by Sun Microsystems, Inc.
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 2003 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.
 */

#include "tkInt.h"
#include "tkWinSendCom.h"
#include "tkWinInt.h"

/*
 * Should be defined in WTypes.h but mingw 1.0 is missing them.
 */

#ifndef _ROTFLAGS_DEFINED
#define _ROTFLAGS_DEFINED
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354







-
+







    Tcl_Obj *displayPtr = NULL;

    /*
     * Process the command options.
     */

    for (i = 1; i < objc; i++) {
	if (Tcl_GetIndexFromObjStruct(interp, objv[i], sendOptions,
	if (Tcl_GetIndexFromObjStruct(NULL, objv[i], sendOptions,
		sizeof(char *), "option", 0, &optind) != TCL_OK) {
	    break;
	}
	if (optind == SEND_ASYNC) {
	    ++async;
	} else if (optind == SEND_DISPLAYOF) {
	    displayPtr = objv[++i];
676
677
678
679
680
681
682
683

684
685
686

687
688
689
690
691
692
693
677
678
679
680
681
682
683

684
685
686

687
688
689
690
691
692
693
694







-
+


-
+







	for (i = 1; SUCCEEDED(hr); i++) {
	    if (i > 1) {
		if (i == 2) {
		    Tcl_DStringInit(&dString);
		    Tcl_DStringAppend(&dString, name, -1);
		    Tcl_DStringAppend(&dString, " #", 2);
		    offset = Tcl_DStringLength(&dString);
		    Tcl_DStringSetLength(&dString, offset+TCL_INTEGER_SPACE);
		    Tcl_DStringSetLength(&dString, offset + TCL_INTEGER_SPACE);
		    actualName = Tcl_DStringValue(&dString);
		}
		sprintf(Tcl_DStringValue(&dString) + offset, "%d", i);
		snprintf(Tcl_DStringValue(&dString) + offset, TCL_INTEGER_SPACE, "%d", i);
	    }

	    hr = BuildMoniker(actualName, &pmk);
	    if (SUCCEEDED(hr)) {

		hr = pROT->lpVtbl->Register(pROT,
		    ROTFLAGS_REGISTRATIONKEEPSALIVE,
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
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







-
-
+












-








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. */
    TCL_UNUSED(void *),
    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.
     */

966
967
968
969
970
971
972
973

974
975
976
977
978
979
980
981
982
983
965
966
967
968
969
970
971

972
973
974

975
976
977
978
979
980
981







-
+


-







 *
 * ----------------------------------------------------------------------
 */

static int
SendEventProc(
    Tcl_Event *eventPtr,
    int flags)
    TCL_UNUSED(int))
{
    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);
Changes to win/tkWinSendCom.c.
428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451







-
+








-
+







 *	The interpreters state and result will be modified.
 *
 * ----------------------------------------------------------------------
 */

static HRESULT
Send(
    TkWinSendCom *comobj,
    TkWinSendCom *obj,
    VARIANT vCmd,
    VARIANT *pvResult,
    EXCEPINFO *pExcepInfo,
    UINT *puArgErr)
{
    HRESULT hr = S_OK;
    int result = TCL_OK;
    VARIANT v;
    Tcl_Interp *interp = comobj->interp;
    Tcl_Interp *interp = obj->interp;
    Tcl_Obj *scriptPtr;
    Tcl_DString ds;
    (void)puArgErr;

    if (interp == NULL) {
	return S_OK;
    }
Changes to win/tkWinTest.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
1
2
3
4
5
6
7


8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29



30



31



32



33



34
35
36
37
38
39
40
41







-
-
+
+










+
+







-
+
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
+
-
-
-
+







/*
 * tkWinTest.c --
 *
 *	Contains commands for platform specific tests for the Windows
 *	platform.
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 2000 by Scriptics Corporation.
 * Copyright (c) 2001 by ActiveState Corporation.
 * Copyright (c) 2000 Scriptics Corporation.
 * Copyright (c) 2001 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"
#undef TCLBOOLWARNING
#define TCLBOOLWARNING(boolPtr) /* needed here because we compile with -Wc++-compat */

HWND tkWinCurrentDialog;

/*
 * Forward declarations of functions defined later in this file:
 */

static int		TestclipboardObjCmd(ClientData clientData,
static Tcl_ObjCmdProc TestclipboardObjCmd;
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwineventObjCmd(ClientData clientData,
static Tcl_ObjCmdProc TestwineventObjCmd;
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestfindwindowObjCmd(ClientData clientData,
static Tcl_ObjCmdProc TestfindwindowObjCmd;
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestgetwindowinfoObjCmd(ClientData clientData,
static Tcl_ObjCmdProc TestgetwindowinfoObjCmd;
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		TestwinlocaleObjCmd(ClientData clientData,
static Tcl_ObjCmdProc TestwinlocaleObjCmd;
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static Tk_GetSelProc		SetSelectionResult;
static Tk_GetSelProc SetSelectionResult;

/*
 *----------------------------------------------------------------------
 *
 * TkplatformtestInit --
 *
 *	Defines commands that test platform specific functionality for Windows
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173







-
+







	    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);
	    snprintf(msgBuf, sizeof(msgBuf), "unknown error: %ld", error);
	}
	msg = msgBuf;
    } else {
	char *msgPtr;

	Tcl_DStringInit(&ds);
	Tcl_WCharToUtfDString(wMsgPtr, wcslen(wMsgPtr), &ds);
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200







-
+







	if (msgPtr[length-1] == '\r') {
	    --length;
	}
	msgPtr[length] = 0;
	msg = msgPtr;
    }

    sprintf(id, "%ld", error);
    snprintf(id, sizeof(id), "%ld", error);
    Tcl_SetErrorCode(interp, "WINDOWS", id, msg, NULL);
    Tcl_AppendToObj(resultPtr, msg, length);
    Tcl_SetObjResult(interp, resultPtr);

    if (length != 0) {
	Tcl_DStringFree(&ds);
    }
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
215
216
217
218
219
220
221

222
223
224
225


226
227
228
229
230
231

232
233
234
235
236
237
238
239







-
+



-
-






-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
SetSelectionResult(
    ClientData dummy,
    TCL_UNUSED(void *),
    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. */
    void *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) {
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282










283
284
285
286
287
288

289
290
291
292

293
294
295
296
297
298
299
300







-
+
















-
-
-
-
-
-
-
-
-
-






-




-
+







 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
TestwineventObjCmd(
    ClientData dummy,	/* Main window for application. */
    TCL_UNUSED(void *),
    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) {
	if (Tcl_GetBooleanFromObj(interp, objv[2], &b) != TCL_OK) {
	    return TCL_ERROR;
	}
	TkWinDialogDebug(b);
	return TCL_OK;
    }

    if (objc < 4) {
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
356
357
358
359
360
361
362

363

364
365
366
367
368
369
370
371
372
373
374
375

376

377

378
379
380
381
382
383
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398

399
400
401
402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
417
418
419
420

421
422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437







-
+
-












-

-
+
-














-
+






-
+










-
+










-
+









-







                             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_ExternalToUtfDString(NULL, buf, -1, &ds), NULL);
	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,
	result = SendMessageA(control, WM_SETTEXT, 0, (LPARAM)Tcl_DStringValue(&ds));
		(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));
	snprintf(buf, sizeof(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",
	snprintf(buf, sizeof(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
 *	Find a Windows window using the FindWindowW 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_UNUSED(void *),
    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;
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
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







-
+










-








    Tcl_ListObjAppendElement(NULL, listObj, Tcl_NewWideIntObj(PTR2INT(hwnd)));
    return TRUE;
}

static int
TestgetwindowinfoObjCmd(
    ClientData dummy,
    TCL_UNUSED(void *),
    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)
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
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







-
+









-
+


-
+








-
+




-
-







	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)));
	    Tcl_NewWideIntObj(GetWindowLongPtrW((HWND)INT2PTR(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))));
	    Tcl_NewWideIntObj(PTR2INT(GetParent((HWND)INT2PTR(hwnd)))));

    childrenObj = Tcl_NewListObj(0, NULL);
    EnumChildWindows((HWND)(size_t)hwnd, EnumChildrenProc, (LPARAM)childrenObj);
    EnumChildWindows((HWND)INT2PTR(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_UNUSED(void *),	/* 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;
}
Changes to win/tkWinWindow.c.
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
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);
    snprintf(buf, TCL_INTEGER_SPACE, "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpScanWindowId --
 *
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
301
302
303
304
305
306
307

308
309
310
311
312
313
314
315







-
+







    Tcl_HashEntry *entryPtr;
    TkWinDrawable *twdPtr = (TkWinDrawable *)w;
    TkWindow *winPtr = TkWinGetWinPtr(w);
    HWND hwnd = Tk_GetHWND(w);
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    display->request++;
    LastKnownRequestProcessed(display)++;

    /*
     * Remove references to the window in the pointer module then release the
     * drawable.
     */

    TkPointerDeadWindow(winPtr);
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

359




360

361
362
363
364
365
366
367
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359
360
361
362
363

364
365
366
367
368
369
370
371







-
+














-
+

+
+
+
+
-
+







 *----------------------------------------------------------------------
 *
 * XMapWindow --
 *
 *	Cause the given window to become visible.
 *
 * Results:
 *	None
 *	Always returns Success or BadWindow.
 *
 * Side effects:
 *	Causes the window state to change, and generates a MapNotify event.
 *
 *----------------------------------------------------------------------
 */

int
XMapWindow(
    Display *display,
    Window w)
{
    XEvent event;
    TkWindow *parentPtr;
    TkWindow *winPtr = TkWinGetWinPtr(w);
    TkWindow *winPtr;

    if (!w) {
	return BadWindow;
    }
    winPtr = TkWinGetWinPtr(w);
    display->request++;
    LastKnownRequestProcessed(display)++;

    ShowWindow(Tk_GetHWND(w), SW_SHOWNORMAL);
    winPtr->flags |= TK_MAPPED;

    /*
     * Check to see if this window is visible now. If all of the parent
     * windows up to the first toplevel are mapped, then this window and its
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+














-
+







	    }
	    if (parentPtr->flags & TK_TOP_HIERARCHY) {
		break;
	    }
	}
    } else {
	event.type = MapNotify;
	event.xmap.serial = display->request;
	event.xmap.serial = LastKnownRequestProcessed(display);
	event.xmap.send_event = False;
	event.xmap.display = display;
	event.xmap.event = winPtr->window;
	event.xmap.window = winPtr->window;
	event.xmap.override_redirect = winPtr->atts.override_redirect;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    }

    /*
     * Generate VisibilityNotify events for this window and its mapped
     * children.
     */

    event.type = VisibilityNotify;
    event.xvisibility.serial = display->request;
    event.xvisibility.serial = LastKnownRequestProcessed(display);
    event.xvisibility.send_event = False;
    event.xvisibility.display = display;
    event.xvisibility.window = winPtr->window;
    event.xvisibility.state = VisibilityUnobscured;
    NotifyVisibility(&event, winPtr);
    return Success;
}
445
446
447
448
449
450
451
452

453
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
449
450
451
452
453
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







-
+













-
+

+
+
+
+
-
+











-
+







 *----------------------------------------------------------------------
 *
 * XUnmapWindow --
 *
 *	Cause the given window to become invisible.
 *
 * Results:
 *	None
 *	Always returns Success or BadWindow.
 *
 * Side effects:
 *	Causes the window state to change, and generates an UnmapNotify event.
 *
 *----------------------------------------------------------------------
 */

int
XUnmapWindow(
    Display *display,
    Window w)
{
    XEvent event;
    TkWindow *winPtr = TkWinGetWinPtr(w);
    TkWindow *winPtr;

    if (!w) {
	return BadWindow;
    }
    winPtr = TkWinGetWinPtr(w);
    display->request++;
    LastKnownRequestProcessed(display)++;

    /*
     * Bug fix: Don't short circuit this routine based on TK_MAPPED because it
     * will be cleared before XUnmapWindow is called.
     */

    ShowWindow(Tk_GetHWND(w), SW_HIDE);
    winPtr->flags &= ~TK_MAPPED;

    if (winPtr->flags & TK_WIN_MANAGED) {
	event.type = UnmapNotify;
	event.xunmap.serial = display->request;
	event.xunmap.serial = LastKnownRequestProcessed(display);
	event.xunmap.send_event = False;
	event.xunmap.display = display;
	event.xunmap.event = winPtr->window;
	event.xunmap.window = winPtr->window;
	event.xunmap.from_configure = False;
	Tk_HandleEvent(&event);
    }
507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529







-
+







int
XMoveResizeWindow(
    Display *display,
    Window w,
    int x, int y,		/* Position relative to parent. */
    unsigned int width, unsigned int height)
{
    display->request++;
    LastKnownRequestProcessed(display)++;
    MoveWindow(Tk_GetHWND(w), x, y, (int) width, (int) height, TRUE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558







-
+







XMoveWindow(
    Display *display,
    Window w,
    int x, int y)		/* Position relative to parent */
{
    TkWindow *winPtr = TkWinGetWinPtr(w);

    display->request++;
    LastKnownRequestProcessed(display)++;

    MoveWindow(Tk_GetHWND(w), x, y, winPtr->changes.width,
	    winPtr->changes.height, TRUE);
    return Success;
}

/*
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589







-
+







XResizeWindow(
    Display *display,
    Window w,
    unsigned int width, unsigned int height)
{
    TkWindow *winPtr = TkWinGetWinPtr(w);

    display->request++;
    LastKnownRequestProcessed(display)++;

    MoveWindow(Tk_GetHWND(w), winPtr->changes.x, winPtr->changes.y, (int)width,
	    (int)height, TRUE);
    return Success;
}

/*
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
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







-
+











-
+







int
XRaiseWindow(
    Display *display,
    Window w)
{
    HWND window = Tk_GetHWND(w);

    display->request++;
    LastKnownRequestProcessed(display)++;
    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++;
    LastKnownRequestProcessed(display)++;
    SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665







-
+







    Window w,
    unsigned int valueMask,
    XWindowChanges *values)
{
    TkWindow *winPtr = TkWinGetWinPtr(w);
    HWND hwnd = Tk_GetHWND(w);

    display->request++;
    LastKnownRequestProcessed(display)++;

    /*
     * Change the shape and/or position of the window.
     */

    if (valueMask & (CWX|CWY|CWWidth|CWHeight)) {
	MoveWindow(hwnd, winPtr->changes.x, winPtr->changes.y,
699
700
701
702
703
704
705
706

707
708
709

710
711
712
713
714
715
716
707
708
709
710
711
712
713

714
715
716

717
718
719
720
721
722
723
724







-
+


-
+







    RECT rc;
    HBRUSH brush;
    HPALETTE oldPalette, palette;
    TkWindow *winPtr;
    HWND hwnd = Tk_GetHWND(w);
    HDC dc = GetDC(hwnd);

    palette = TkWinGetPalette(display->screens[0].cmap);
    palette = TkWinGetPalette(DefaultColormapOfScreen(ScreenOfDisplay(display, 0)));
    oldPalette = SelectPalette(dc, palette, FALSE);

    display->request++;
    LastKnownRequestProcessed(display)++;

    winPtr = TkWinGetWinPtr(w);
    brush = CreateSolidBrush(winPtr->atts.background_pixel);
    GetWindowRect(hwnd, &rc);
    rc.right = rc.right - rc.left;
    rc.bottom = rc.bottom - rc.top;
    rc.left = rc.top = 0;
748
749
750
751
752
753
754



























755
756
757
758
759
760
761
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    XSetWindowAttributes* attributes)
{
    if (valueMask & CWCursor) {
	XDefineCursor(display, w, attributes->cursor);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * XReparentWindow --
 *
 *	TODO: currently placeholder to satisfy Xlib stubs.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	TODO.
 *
 *----------------------------------------------------------------------
 */

int
XReparentWindow(
    Display *display,
    Window w,
    Window parent,
    int x,
    int y)
{
    return BadWindow;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinSetWindowPos --
 *
 *	Adjust the stacking order of a window relative to a second window (or
827
828
829
830
831
832
833
834

835
836
837
838
839
840
841
862
863
864
865
866
867
868

869
870
871
872
873
874
875
876







-
+







    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++;
	LastKnownRequestProcessed(display)++;
	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
Changes to win/tkWinWm.c.
1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17









-
+







/*
 * tkWinWm.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) 1995-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-2000 by Scriptics Corporation.
 * 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.
 */

#include "tkWinInt.h"
#include <shellapi.h>
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76







-
+







				 * 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)
    ((Tk_Offset(ProtocolHandler, command) + 1) + cmdLength)

/*
 * Helper type passed via lParam to TkWmStackorderToplevelEnumProc
 */

typedef struct TkWmStackorderToplevelPair {
    Tcl_HashTable *table;
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141







-
+







    WORD idReserved;		/* Reserved */
    WORD idType;		/* Resource type (1 for icons) */
    WORD idCount;		/* How many images? */
    ICONDIRENTRY idEntries[1];	/* The entries for each image */
} ICONDIR, *LPICONDIR;

/*
 * A pointer to one of these strucutures is associated with each toplevel.
 * A pointer to one of these structures is associated with each toplevel.
 * This allows us to free up all memory associated with icon resources when a
 * window is deleted or if the window's icon is changed. They are simply
 * reference counted according to:
 *
 * (1) How many WmInfo structures point to this object
 * (2) Whether the ThreadSpecificData defined in this file contains a pointer
 *     to this object.
354
355
356
357
358
359
360
361

362
363
364
365
366
367

368
369
370
371
372
373
374
354
355
356
357
358
359
360

361
362
363
364
365
366

367
368
369
370
371
372
373
374







-
+





-
+







#define EX_TRANSIENT_STYLE (WS_EX_DLGMODALFRAME)

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		TopLevelReqProc(void *, Tk_Window);
static void		RemapWindows(TkWindow *winPtr, HWND parentHWND);

static const Tk_GeomMgr wmMgrType = {
    "wm",			/* name */
    TopLevelReqProc,		/* requestProc */
    NULL,			/* lostContentProc */
    NULL,			/* lostSlaveProc */
};

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
419
420
421
422
423
424
425
426

427
428
429


430
431
432
433

434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
419
420
421
422
423
424
425

426
427


428
429
430
431
432

433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448







-
+

-
-
+
+



-
+





+


-







			    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);
static void		TopLevelEventProc(ClientData clientData,
static void		TopLevelEventProc(void *clientData,
			    XEvent *eventPtr);
static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
static void		UpdateGeometryInfo(ClientData clientData);
static void		TopLevelReqProc(void *dummy, Tk_Window tkwin);
static void		UpdateGeometryInfo(void *clientData);
static void		UpdateWrapper(TkWindow *winPtr);
static LRESULT CALLBACK	WmProc(HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam);
static void		WmWaitVisibilityOrMapProc(ClientData clientData,
static void		WmWaitVisibilityOrMapProc(void *clientData,
			    XEvent *eventPtr);
static BlockOfIconImagesPtr ReadIconOrCursorFromFile(Tcl_Interp *interp,
			    Tcl_Obj* fileName, BOOL isIcon);
static WinIconPtr	ReadIconFromFile(Tcl_Interp *interp,
			    Tcl_Obj *fileName);
static BOOL		AdjustIconImagePointers(LPICONIMAGE lpImage);
static WinIconPtr	GetIconFromPixmap(Display *dsPtr, Pixmap pixmap);
static int		ReadICOHeader(Tcl_Channel channel);
static BOOL		AdjustIconImagePointers(LPICONIMAGE lpImage);
static HICON		MakeIconOrCursorFromResource(LPICONIMAGE lpIcon,
			    BOOL isIcon);
static HICON		GetIcon(WinIconPtr titlebaricon, int icon_size);
static int		WinSetIcon(Tcl_Interp *interp,
			    WinIconPtr titlebaricon, Tk_Window tkw);
static void		FreeIconBlock(BlockOfIconImagesPtr lpIR);
static void		DecrIconRefCount(WinIconPtr titlebaricon);
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
867
868
869
870
871
872
873

874
875
876
877
878
879
880
881







-
+







    if (!initialized) {
	Tcl_MutexLock(&winWmMutex);
	if (!initialized) {
	    WNDCLASSW windowClass;

	    initialized = 1;

	    ZeroMemory(&windowClass, sizeof(WNDCLASSW));
	    memset(&windowClass, 0, 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");
1265
1266
1267
1268
1269
1270
1271
1272

1273
1274
1275
1276
1277
1278
1279
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1279







-
+







		if (res != 0) {
		    DestroyIcon(sfi.hIcon);
		}
		DestroyIcon(sfiSM.hIcon);
		Tcl_DStringFree(&ds2);
		return NULL;
	    }
	    ZeroMemory(lpIR, size);
	    memset(lpIR, 0, size);

	    lpIR->nNumImages		= ((res != 0) ? 2 : 1);
	    lpIR->IconImages[0].Width	= 16;
	    lpIR->IconImages[0].Height	= 16;
	    lpIR->IconImages[0].Colors	= 4;
	    lpIR->IconImages[0].hIcon	= sfiSM.hIcon;

1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1579
1580
1581
1582
1583
1584
1585





1586
1587
1588
1589
1590
1591
1592







-
-
-
-
-







	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));

1667
1668
1669
1670
1671
1672
1673
1674

1675
1676
1677
1678
1679
1680
1681
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673
1674
1675
1676







-
+







	}

	/*
	 * Read it in.
	 */

	dwBytesRead = Tcl_Read(channel, (char *)lpIR->IconImages[i].lpBits,
		(int) lpIDE[i].dwBytesInRes);
		(int)lpIDE[i].dwBytesInRes);
	if (dwBytesRead != lpIDE[i].dwBytesInRes) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "error reading file: %s", Tcl_PosixError(interp)));
	    goto readError;
	}

	/*
1907
1908
1909
1910
1911
1912
1913
1914

1915
1916
1917
1918
1919
1920
1921
1902
1903
1904
1905
1906
1907
1908

1909
1910
1911
1912
1913
1914
1915
1916







-
+







{
    WmInfo *wmPtr = (WmInfo *)ckalloc(sizeof(WmInfo));

    /*
     * Initialize full structure, then set what isn't NULL
     */

    ZeroMemory(wmPtr, sizeof(WmInfo));
    memset(wmPtr, 0, sizeof(WmInfo));
    winPtr->wmInfoPtr = wmPtr;
    wmPtr->winPtr = winPtr;
    wmPtr->hints.flags = InputHint | StateHint;
    wmPtr->hints.input = True;
    wmPtr->hints.initial_state = NormalState;
    wmPtr->hints.icon_pixmap = None;
    wmPtr->hints.icon_window = None;
2736
2737
2738
2739
2740
2741
2742
2743

2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2731
2732
2733
2734
2735
2736
2737

2738
2739


2740
2741
2742
2743
2744
2745
2746







-
+

-
-







 *	A window property may get updated.
 *
 *--------------------------------------------------------------
 */

void
TkWmSetClass(
    TkWindow *winPtr)		/* Newly-created top-level window. */
    TCL_UNUSED(TkWindow *))	/* Newly-created top-level window. */
{
    (void)winPtr;

    /* Do nothing */
    return;
}

/*
 *----------------------------------------------------------------------
 *
2763
2764
2765
2766
2767
2768
2769
2770

2771
2772
2773
2774
2775
2776
2777
2756
2757
2758
2759
2760
2761
2762

2763
2764
2765
2766
2767
2768
2769
2770







-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_WmObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    void *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",
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
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







-
+










-
+









-
-
+
+













-
-
+
+







	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;
    int 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);
    argv1 = Tcl_GetStringFromObj(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));
	    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 (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings,
	    "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
	goto wrongNumArgs;
    }

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
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







-
+







-










-
-
-
-
+
+
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmAspectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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);
	    results[0] = Tcl_NewIntObj(wmPtr->minAspect.x);
	    results[1] = Tcl_NewIntObj(wmPtr->minAspect.y);
	    results[2] = Tcl_NewIntObj(wmPtr->maxAspect.x);
	    results[3] = Tcl_NewIntObj(wmPtr->maxAspect.y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->sizeHintsFlags &= ~PAspect;
    } else {
3022
3023
3024
3025
3026
3027
3028
3029
3030


3031
3032
3033
3034
3035
3036
3037
3014
3015
3016
3017
3018
3019
3020


3021
3022
3023
3024
3025
3026
3027
3028
3029







-
-
+
+







    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 boolValue;
    int i, 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
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







-
+



-
+



-
+



-
+




-
+
-
-
-







	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_NewBooleanObj(style & WS_DISABLED));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-fullscreen", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((wmPtr->flags & WM_FULLSCREEN) != 0));
		Tcl_NewBooleanObj(wmPtr->flags & WM_FULLSCREEN));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-toolwindow", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOOLWINDOW) != 0));
		Tcl_NewBooleanObj(exStyle & WS_EX_TOOLWINDOW));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewStringObj("-topmost", -1));
	Tcl_ListObjAppendElement(NULL, objPtr,
		Tcl_NewWideIntObj((exStyle & WS_EX_TOPMOST) != 0));
		Tcl_NewBooleanObj(exStyle & WS_EX_TOPMOST));
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }
    for (i = 3; i < objc; i += 2) {
	string = TkGetStringFromObj(objv[i], &length);
	string = Tcl_GetStringFromObj(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;
3106
3107
3108
3109
3110
3111
3112






3113
3114
3115
3116
3117
3118
3119
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114







+
+
+
+
+
+







	    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 if (i == 3) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad attribute \"%s\": must be -alpha, -transparentcolor, -disabled, -fullscreen, -toolwindow, or -topmost",
		    string));
	    Tcl_SetErrorCode(interp, "TK", "WM", "ATTR", "UNRECOGNIZED", NULL);
	    return TCL_ERROR;
	} else {
	    goto configArgs;
	}
	if (styleBit == WS_EX_LAYERED) {
	    if (objc == 4) {
		if (string[1] == 'a') {		/* -alpha */
		    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(wmPtr->alpha));
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
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







-
+









-
+







		    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);
		    (void)Tcl_GetStringFromObj(objv[i+1], &length);

		    if (length == 0) {
			/* reset to no transparent color */
			if (wmPtr->crefObj) {
			    Tcl_DecrRefCount(wmPtr->crefObj);
			    wmPtr->crefObj = NULL;
			}
		    } else {
			XColor *cPtr =
			    Tk_GetColor(interp, tkwin, Tk_GetUid(crefstr));
			    Tk_AllocColorFromObj(interp, tkwin, objv[i+1]);
			if (cPtr == NULL) {
			    return TCL_ERROR;
			}

			if (wmPtr->crefObj) {
			    Tcl_DecrRefCount(wmPtr->crefObj);
			}
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
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







-
+





-
-
+
+


-
+




-
-
+
+







			    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_GetBooleanFromObj(interp, objv[i+1], &boolValue)
			    != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (config_fullscreen) {
		if (objc == 4) {
		    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
			    (wmPtr->flags & WM_FULLSCREEN) != 0));
		    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
			    wmPtr->flags & WM_FULLSCREEN));
		} else {
		    fullscreen_attr_changed = 1;
		    fullscreen_attr = boolean;
		    fullscreen_attr = boolValue;
		}
		config_fullscreen = 0;
	    } else if (objc == 4) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj((*stylePtr & styleBit) != 0));
	    } else if (boolean) {
			Tcl_NewBooleanObj(*stylePtr & styleBit));
	    } else if (boolValue) {
		*stylePtr |= styleBit;
	    } else {
		*stylePtr &= ~styleBit;
	    }
	}
	if ((styleBit == WS_EX_TOPMOST) && (wmPtr->wrapper != NULL)) {
	    /*
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
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







-
+







-
+
-












-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmClientCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    TkSizeT length;
    int 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);
    argv3 = Tcl_GetStringFromObj(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"));
3355
3356
3357
3358
3359
3360
3361
3362

3363
3364
3365
3366
3367
3368
3369
3349
3350
3351
3352
3353
3354
3355

3356
3357
3358
3359
3360
3361
3362
3363







-
+







    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	XTextProperty textProp;

	if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp)
		!= 0) {
	    XSetWMClientMachine(winPtr->display, winPtr->window,
		    &textProp);
	    XFree((char *) textProp.value);
	    XFree((char *)textProp.value);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
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
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







-
+
+















-
+







    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;
    int i, windowObjc;
    int 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]));
		    TkNewWindowObj((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;
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
3469
3470
3471
3472
3473
3474
3475

3476
3477
3478
3479
3480
3481
3482
3483
3484
3485

3486
3487
3488
3489
3490
3491
3492







-
+









-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmCommandCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->cmdArgv != NULL) {
3544
3545
3546
3547
3548
3549
3550
3551

3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3538
3539
3540
3541
3542
3543
3544

3545
3546
3547
3548
3549
3550
3551

3552
3553
3554
3555
3556
3557
3558







-
+






-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmDeiconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
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
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







-
+













-











-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFocusmodelCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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) {
    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;
    }
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
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
WmForgetCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TCL_UNUSED(Tk_Window),	/* 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. */
    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;
    (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);
	/*
	 * 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 */
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
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







-
+








-












-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmFrameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    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);
    snprintf(buf, sizeof(buf), "0x%" TCL_Z_MODIFIER "x", (size_t)hwnd);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
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
3739
3740
3741
3742
3743
3744
3745

3746
3747
3748
3749
3750
3751
3752
3753
3754
3755

3756
3757
3758
3759
3760
3761
3762







-
+









-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGeometryCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (void)tkwin;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
	return TCL_ERROR;
    }

    if (objc == 3) {
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
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







-
+







-










-
-
-
-
+
+
+
+










-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmGridCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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);
	    results[0] = Tcl_NewIntObj(wmPtr->reqGridWidth);
	    results[1] = Tcl_NewIntObj(wmPtr->reqGridHeight);
	    results[2] = Tcl_NewIntObj(wmPtr->widthInc);
	    results[3] = Tcl_NewIntObj(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.
	 */

	wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
	wmPtr->sizeHintsFlags &= ~PBaseSize;
	if (wmPtr->width != -1) {
	    wmPtr->width = winPtr->reqWidth + (wmPtr->width
		    - wmPtr->reqGridWidth)*wmPtr->widthInc;
	    wmPtr->height = winPtr->reqHeight + (wmPtr->height
		    - wmPtr->reqGridHeight)*wmPtr->heightInc;
	}
	wmPtr->widthInc = 1;
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
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







-
+











-
+







    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;
    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 = TkGetStringFromObj(objv[3], &length);
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
	}
	wmPtr->leaderName = NULL;
    } else {
3983
3984
3985
3986
3987
3988
3989
3990

3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
3968
3969
3970
3971
3972
3973
3974

3975
3976
3977
3978
3979
3980
3981
3982
3983

3984
3985
3986
3987
3988
3989
3990







-
+








-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconbitmapCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    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.
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
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







-
+






-








-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconifyCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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",
		    "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(
4159
4160
4161
4162
4163
4164
4165
4166

4167
4168
4169
4170
4171
4172
4173
4142
4143
4144
4145
4146
4147
4148

4149
4150
4151
4152
4153
4154
4155
4156







-
+







		"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\"",
		"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;
}
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
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







-
+







-
+
-













-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconnameCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    TkSizeT length;
    int 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);
	argv3 = Tcl_GetStringFromObj(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;
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
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







-
+








+
-
+








-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconphotoCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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. */
{
    TkWindow *useWinPtr = winPtr; /* window to apply to (NULL if -default) */
    Tk_PhotoHandle photo;
    Tk_PhotoImageBlock block;
    int i;
    int i, width, height, idx, bufferSize, startObj = 3;
    int 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;
    }

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
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







-
+















-
+






-
+







     */

    size = sizeof(BlockOfIconImages) + (sizeof(ICONIMAGE) * (objc-startObj-1));
    lpIR = (BlockOfIconImagesPtr)attemptckalloc(size);
    if (lpIR == NULL) {
	return TCL_ERROR;
    }
    ZeroMemory(lpIR, size);
    memset(lpIR, 0, 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));
	memset(&iconInfo, 0, sizeof(iconInfo));
	iconInfo.fIcon = TRUE;

	/*
	 * Create device-independent color bitmap.
	 */

	ZeroMemory(&bmInfo, sizeof bmInfo);
	memset(&bmInfo, 0, 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;

4431
4432
4433
4434
4435
4436
4437
4438

4439
4440
4441
4442
4443
4444
4445
4413
4414
4415
4416
4417
4418
4419

4420
4421
4422
4423
4424
4425
4426
4427







-
+







	    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);
	memset(bgraMask.ptr, 0, width*height/8);

	/*
	 * Create an icon from the bitmaps.
	 */

	hIcon = CreateIconIndirect(&iconInfo);
	DeleteObject(iconInfo.hbmColor);
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
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







-
+







-









-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmIconpositionCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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);
	    results[0] = Tcl_NewIntObj(wmPtr->hints.icon_x);
	    results[1] = Tcl_NewIntObj(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 {
4565
4566
4567
4568
4569
4570
4571
4572

4573
4574
4575
4576
4577
4578
4579
4546
4547
4548
4549
4550
4551
4552

4553
4554
4555
4556
4557
4558
4559
4560







-
+








    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));
	    Tcl_SetObjResult(interp, TkNewWindowObj(wmPtr->icon));
	}
	return TCL_OK;
    }
    if (*Tcl_GetString(objv[3]) == '\0') {
	wmPtr->hints.flags &= ~IconWindowHint;
	if (wmPtr->icon != NULL) {
	    /*
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
4639
4640
4641
4642
4643
4644
4645

4646
4647
4648


4649
4650
4651
4652
4653



4654
4655
4656
4657
4658
4659
4660







-
+


-
-
+
+



-
-
-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmManageCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    TCL_UNUSED(Tk_Window),	/* 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. */
    TCL_UNUSED(int),		/* Number of arguments. */
    TCL_UNUSED(Tcl_Obj *const *)) /* 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);
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
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







-
+







-









-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMaxsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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);
	results[0] = Tcl_NewIntObj(width);
	results[1] = Tcl_NewIntObj(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;
    }
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
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







-
+







-









-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmMinsizeCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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);
	results[0] = Tcl_NewIntObj(width);
	results[1] = Tcl_NewIntObj(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;
    }
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
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







-
+






-
+

-

















-
+


-
+


-
+

-
+






-
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmOverrideredirectCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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 boolean, curValue;
    int boolValue, 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));
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(curValue));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
    if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
	return TCL_ERROR;
    }
    if (curValue != boolean) {
    if (curValue != boolValue) {
	if (winPtr->flags & TK_EMBEDDED) {
	    SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolean, 0);
	    SendMessageW(wmPtr->wrapper, TK_OVERRIDEREDIRECT, boolValue, 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;
	    atts.override_redirect = boolValue ? True : False;
	    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		    &atts);
	    if (!(wmPtr->flags & (WM_NEVER_MAPPED))
		    && !(winPtr->flags & TK_EMBEDDED)) {
		UpdateWrapper(winPtr);
	    }
	}
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
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







-
+













-



















-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmPositionfromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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) {
	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;
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
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







-
+









-
+

-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmProtocolCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    int 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) {
	/*
5027
5028
5029
5030
5031
5032
5033
5034

5035
5036
5037
5038
5039
5040
5041
5000
5001
5002
5003
5004
5005
5006

5007
5008
5009
5010
5011
5012
5013
5014







-
+







	    } else {
		prevPtr->nextPtr = protPtr->nextPtr;
	    }
	    Tcl_EventuallyFree(protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = TkGetStringFromObj(objv[4], &cmdLength);
    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);
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
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







-
+







-








-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmResizableCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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));
	results[0] = Tcl_NewBooleanObj(!(wmPtr->flags&WM_WIDTH_NOT_RESIZABLE));
	results[1] = Tcl_NewBooleanObj(!(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;
    }
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
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







-
+













-




















-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmSizefromCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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) {
	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;
5218
5219
5220
5221
5222
5223
5224
5225

5226
5227
5228
5229
5230
5231
5232
5189
5190
5191
5192
5193
5194
5195

5196
5197
5198
5199
5200
5201
5202
5203







-
+








    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));
			TkNewWindowObj((Tk_Window) *windowPtr));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	    ckfree(windows);
	    return TCL_OK;
	} else {
	    return TCL_ERROR;
	}
5286
5287
5288
5289
5290
5291
5292
5293
5294


5295
5296
5297
5298
5299
5300
5301
5302

5303
5304
5305
5306
5307
5308
5309
5257
5258
5259
5260
5261
5262
5263


5264
5265
5266
5267
5268
5269
5270
5271
5272

5273
5274
5275
5276
5277
5278
5279
5280







-
-
+
+







-
+







	    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) {
	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_NewWideIntObj(result));
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
	return TCL_OK;
    }
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+













-













-
-
+
+







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmStateCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (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) {
	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) {
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
5430
5431
5432
5433
5434
5435
5436

5437
5438
5439
5440
5441
5442
5443
5444

5445
5446

5447
5448
5449
5450
5451
5452
5453







-
+







-
+

-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmTitleCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    TkSizeT length;
    int length;
    HWND wrapper;
    (void)tkwin;

    if (objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
	return TCL_ERROR;
    }

    if (winPtr->flags & TK_EMBEDDED) {
5503
5504
5505
5506
5507
5508
5509
5510

5511
5512
5513
5514
5515
5516
5517
5472
5473
5474
5475
5476
5477
5478

5479
5480
5481
5482
5483
5484
5485
5486







-
+







	    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);
	argv3 = Tcl_GetStringFromObj(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);
5549
5550
5551
5552
5553
5554
5555
5556

5557
5558
5559
5560
5561

5562
5563
5564
5565
5566
5567
5568
5518
5519
5520
5521
5522
5523
5524

5525
5526
5527
5528
5529

5530
5531
5532
5533
5534
5535
5536
5537







-
+




-
+







    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?");
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (containerPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) containerPtr));
	    Tcl_SetObjResult(interp, TkNewWindowObj((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
5598
5599
5600
5601
5602
5603
5604
5605

5606
5607
5608
5609
5610
5611

5612
5613
5614

5615
5616
5617
5618
5619
5620
5621
5567
5568
5569
5570
5571
5572
5573

5574
5575
5576
5577
5578
5579

5580
5581
5582

5583
5584
5585
5586
5587
5588
5589
5590







-
+





-
+


-
+







	    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",
		    "can't make \"%s\" a master: 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) {
	    w = (TkWindow *)w->wmInfoPtr->containerPtr) {
	    if (w == winPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't set \"%s\" as container: would cause management loop",
		    "setting \"%s\" as master creates a transient/master cycle",
		    Tk_PathName(containerPtr)));
		Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
		return TCL_ERROR;
	    }
	}
	if (containerPtr != wmPtr->containerPtr) {
	    /*
5666
5667
5668
5669
5670
5671
5672
5673

5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5635
5636
5637
5638
5639
5640
5641

5642
5643
5644
5645
5646
5647
5648

5649
5650
5651
5652
5653
5654
5655







-
+






-







 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
WmWithdrawCmd(
    Tk_Window tkwin,		/* Main window of the application. */
    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;
    (void)tkwin;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
5720
5721
5722
5723
5724
5725
5726
5727

5728
5729
5730
5731
5732
5733
5734
5688
5689
5690
5691
5692
5693
5694

5695
5696
5697
5698
5699
5700
5701
5702







-
+







	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

static void
WmWaitVisibilityOrMapProc(
    ClientData clientData,	/* Pointer to window. */
    void *clientData,	/* Pointer to window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkWindow *winPtr = (TkWindow *)clientData;
    TkWindow *containerPtr = winPtr->wmInfoPtr->containerPtr;

    if (containerPtr == NULL)
	return;
5818
5819
5820
5821
5822
5823
5824
5825

5826
5827
5828
5829
5830
5831
5832
5833
5786
5787
5788
5789
5790
5791
5792

5793

5794
5795
5796
5797
5798
5799
5800







-
+
-







	return;
    }

    if ((wmPtr->reqGridWidth == reqWidth)
	    && (wmPtr->reqGridHeight == reqHeight)
	    && (wmPtr->widthInc == widthInc)
	    && (wmPtr->heightInc == heightInc)
	    && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
	    && ((wmPtr->sizeHintsFlags & PBaseSize) == PBaseSize)) {
		    == (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
5850
5851
5852
5853
5854
5855
5856
5857

5858
5859
5860
5861
5862
5863
5864
5817
5818
5819
5820
5821
5822
5823

5824
5825
5826
5827
5828
5829
5830
5831







-
+







     */

    wmPtr->gridWin = tkwin;
    wmPtr->reqGridWidth = reqWidth;
    wmPtr->reqGridHeight = reqHeight;
    wmPtr->widthInc = widthInc;
    wmPtr->heightInc = heightInc;
    wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
    wmPtr->sizeHintsFlags |= PBaseSize;
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
}

/*
5901
5902
5903
5904
5905
5906
5907
5908

5909
5910
5911
5912
5913
5914
5915
5868
5869
5870
5871
5872
5873
5874

5875
5876
5877
5878
5879
5880
5881
5882







-
+







    }

    if (tkwin != wmPtr->gridWin) {
	return;
    }

    wmPtr->gridWin = NULL;
    wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
    wmPtr->sizeHintsFlags &= ~PBaseSize;
    if (wmPtr->width != -1) {
	wmPtr->width = winPtr->reqWidth + (wmPtr->width
		- wmPtr->reqGridWidth)*wmPtr->widthInc;
	wmPtr->height = winPtr->reqHeight + (wmPtr->height
		- wmPtr->reqGridHeight)*wmPtr->heightInc;
    }
    wmPtr->widthInc = 1;
5937
5938
5939
5940
5941
5942
5943
5944

5945
5946
5947
5948
5949
5950
5951
5904
5905
5906
5907
5908
5909
5910

5911
5912
5913
5914
5915
5916
5917
5918







-
+







 *	the structural change.
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelEventProc(
    ClientData clientData,	/* Window for which event occurred. */
    void *clientData,	/* Window for which event occurred. */
    XEvent *eventPtr)		/* Event that just happened. */
{
    TkWindow *winPtr = (TkWindow *)clientData;

    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;

5982
5983
5984
5985
5986
5987
5988
5989

5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
5949
5950
5951
5952
5953
5954
5955

5956
5957
5958
5959
5960

5961
5962
5963
5964
5965
5966
5967







-
+




-







 *	happens as a when-idle action).
 *
 *----------------------------------------------------------------------
 */

static void
TopLevelReqProc(
    ClientData dummy,		/* Not used. */
    TCL_UNUSED(void *),
    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));
	}
6025
6026
6027
6028
6029
6030
6031
6032

6033
6034
6035
6036
6037
6038
6039
5991
5992
5993
5994
5995
5996
5997

5998
5999
6000
6001
6002
6003
6004
6005







-
+







 *	from happening.
 *
 *----------------------------------------------------------------------
 */

static void
UpdateGeometryInfo(
    ClientData clientData)	/* Pointer to the window's record. */
    void *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;
6534
6535
6536
6537
6538
6539
6540
6541

6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6500
6501
6502
6503
6504
6505
6506

6507
6508
6509
6510
6511
6512
6513


6514
6515
6516
6517
6518
6519
6520







-
+






-
-







 *	Vroot window information is refreshed if it is out of date.
 *
 *----------------------------------------------------------------------
 */

void
Tk_GetVRootGeometry(
    Tk_Window tkwin,		/* Window whose virtual root is to be
    TCL_UNUSED(Tk_Window),/* 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);
}

/*
6702
6703
6704
6705
6706
6707
6708
6709

6710
6711
6712
6713
6714
6715
6716
6666
6667
6668
6669
6670
6671
6672

6673
6674
6675
6676
6677
6678
6679
6680







-
+







    TkWindow *childWinPtr;

    TkWmStackorderToplevelPair *pair =
	    (TkWmStackorderToplevelPair *) lParam;

    /*fprintf(stderr, "Looking up HWND %d\n", hwnd);*/

    hPtr = Tcl_FindHashEntry(pair->table, 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.
	 */

7362
7363
7364
7365
7366
7367
7368
7369

7370
7371
7372
7373
7374
7375
7376
7326
7327
7328
7329
7330
7331
7332

7333
7334
7335
7336
7337
7338
7339
7340







-
+







    XEvent event;

    /*
     * Generate a ConfigureNotify event.
     */

    event.type = ConfigureNotify;
    event.xconfigure.serial = winPtr->display->request;
    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.border_width = winPtr->changes.border_width;
    event.xconfigure.override_redirect = winPtr->atts.override_redirect;
    event.xconfigure.x = winPtr->changes.x;
7938
7939
7940
7941
7942
7943
7944
7945

7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960



7961
7962

7963
7964
7965
7966
7967
7968
7969
7902
7903
7904
7905
7906
7907
7908

7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921



7922
7923
7924
7925

7926
7927
7928
7929
7930
7931
7932
7933







-
+












-
-
-
+
+
+

-
+







	/*
	 * Display and/or color resolution changed.
	 */

	winPtr = GetTopLevel(hwnd);
	if (winPtr) {
	    Screen *screen = Tk_Screen(winPtr);
	    if (screen->root_depth != (int) wParam) {
	    if (DefaultDepthOfScreen(screen) != (int) wParam) {
		/*
		 * Color resolution changed, so do extensive rebuild of
		 * display parameters. This will affect the display for all Tk
		 * windows. We will receive this event for each toplevel, but
		 * this check makes us update only once, for the first
		 * toplevel that receives the message.
		 */

		TkWinDisplayChanged(Tk_Display(winPtr));
	    } else {
		HDC dc = GetDC(NULL);

		screen->width = LOWORD(lParam);		/* horizontal res */
		screen->height = HIWORD(lParam);	/* vertical res */
		screen->mwidth = MulDiv(screen->width, 254,
		WidthOfScreen(screen) = LOWORD(lParam);		/* horizontal res */
		HeightOfScreen(screen) = HIWORD(lParam);	/* vertical res */
		WidthMMOfScreen(screen) = MulDiv(WidthOfScreen(screen), 254,
			GetDeviceCaps(dc, LOGPIXELSX) * 10);
		screen->mheight = MulDiv(screen->height, 254,
		HeightMMOfScreen(screen) = MulDiv(HeightOfScreen(screen), 254,
			GetDeviceCaps(dc, LOGPIXELSY) * 10);
		ReleaseDC(NULL, dc);
	    }
	    if (Tk_Depth(winPtr) != (int) wParam) {
		/*
		 * Defer the window depth check to here so that each toplevel
		 * will properly update depth info.
8006
8007
8008
8009
8010
8011
8012
8013

8014
8015
8016
8017
8018
8019
8020
7970
7971
7972
7973
7974
7975
7976

7977
7978
7979
7980
7981
7982
7983
7984







-
+







	result = 0;
	goto done;

    case WM_NCHITTEST: {
	winPtr = GetTopLevel(hwnd);
	if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) {
	    /*
	     * This window is outside the grab heirarchy, so don't let any of
	     * This window is outside the grab hierarchy, so don't let any of
	     * the normal non-client processing occur. Note that this
	     * implementation is not strictly correct because the grab might
	     * change between now and when the event would have been processed
	     * by Tk, but it's close enough.
	     */

	    result = HTCLIENT;
8121
8122
8123
8124
8125
8126
8127
8128

8129
8130
8131
8132
8133
8134
8135
8085
8086
8087
8088
8089
8090
8091

8092
8093
8094
8095
8096
8097
8098
8099







-
+








    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,
	} else if (!Tk_TranslateWinEvent(child, message, wParam, lParam,
		&result)) {
	    result = DefWindowProcW(hwnd, message, wParam, lParam);
	}
    } else {
	result = DefWindowProcW(hwnd, message, wParam, lParam);
    }

8325
8326
8327
8328
8329
8330
8331
8332

8333
8334
8335
8336
8337
8338
8339
8289
8290
8291
8292
8293
8294
8295

8296
8297
8298
8299
8300
8301
8302
8303







-
+







    if (!IsWindow(eventPtr->hwnd)) {
	return 1;
    }

    /*
     * If the toplevel is in the middle of a move or size operation then
     * we must delay handling of this event to avoid stealing the focus
     * while the window manage is in control.
     * while the window manager is in control.
     */

    if (eventPtr->flagPtr && *eventPtr->flagPtr) {
	return 0;
    }

    /*
8393
8394
8395
8396
8397
8398
8399
8400

8401
8402
8403
8404
8405
8406
8407
8357
8358
8359
8360
8361
8362
8363

8364
8365
8366
8367
8368
8369
8370
8371







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelWithdraw --
 *
 *	This function is to be used by a window manage to withdraw a toplevel
 *	This function is to be used by a window manager to withdraw a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May withdraw the toplevel window.
8420
8421
8422
8423
8424
8425
8426
8427

8428
8429
8430
8431
8432
8433
8434
8384
8385
8386
8387
8388
8389
8390

8391
8392
8393
8394
8395
8396
8397
8398







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelIconify --
 *
 *	This function is to be used by a window manage to iconify a toplevel
 *	This function is to be used by a window manager to iconify a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May iconify the toplevel window.
8444
8445
8446
8447
8448
8449
8450
8451

8452
8453
8454
8455
8456
8457
8458
8408
8409
8410
8411
8412
8413
8414

8415
8416
8417
8418
8419
8420
8421
8422







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelDeiconify --
 *
 *	This function is to be used by a window manage to deiconify a toplevel
 *	This function is to be used by a window manager to deiconify a toplevel
 *	window.
 *
 * Results:
 *	none
 *
 * Side effects:
 *	May deiconify the toplevel window.
8511
8512
8513
8514
8515
8516
8517
8518

8519
8520
8521
8522
8523
8524
8525
8475
8476
8477
8478
8479
8480
8481

8482
8483
8484
8485
8486
8487
8488
8489







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinGeometryIsControlledByWm --
 *
 *	This function is to be used by a window manage to see if wm has
 *	This function is to be used by a window manager to see if wm has
 *	canceled geometry control.
 *
 * Results:
 *	0 - if the window manager has canceled its control
 *	1 - if the window manager controls the geometry
 *
 * Side effects:
8621
8622
8623
8624
8625
8626
8627
8628

8629
8630
8631
8632
8633
8634
8635
8585
8586
8587
8588
8589
8590
8591

8592
8593
8594
8595
8596
8597
8598
8599







-
+







}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelDetachWindow --
 *
 *	This function is to be usd for changing a toplevel's wrapper or
 *	This function is to be used for changing a toplevel's wrapper or
 *	container.
 *
 * Results:
 *	The window's wrapper/container is removed.
 *
 * Side effects:
 *	None.
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
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







-
+





+


+
+
+
+
+
+
+
+
+
+







/*
 * 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.
 * 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.
 */

#define XLIB_ILLEGAL_ACCESS
#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 0x0550 /* IE 5.5 */
#endif

#include <commctrl.h>
#ifdef _MSC_VER
#   pragma comment (lib, "comctl32.lib")
#   pragma comment (lib, "advapi32.lib")
#endif

/*
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
127
128
129
130
131
132
133

134
135
136
137
138

139
140

141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+




-


-
+







-
+







 *----------------------------------------------------------------------
 */

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
    TCL_UNUSED(Tk_Window))		/* 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");
	HANDLE 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,
	snprintf(buffer+1, sizeof(buffer)-1, "indows %d.%d %d %s", (int)os.dwMajorVersion,
		(int)os.dwMinorVersion, (int)os.dwBuildNumber,
#ifdef _WIN64
		"Win64"
#else
		"Win32"
#endif
	);
377
378
379
380
381
382
383
























384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

401
402
403
404
405
406
407
408
409
410
411
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435
436


437
438
439
440
441
442
443







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
















-
+


-
-







    }
    return tkWinTheme;
}

/*
 *----------------------------------------------------------------------
 *
 * TkWinGetPlatformId --
 *
 *	Determines whether running under NT, 95, or Win32s, to allow runtime
 *	conditional code. Win32s is no longer supported.
 *
 * Results:
 *	The return value is always:
 *		VER_PLATFORM_WIN32_NT	Win32 on Windows XP, Vista, Windows 7, Windows 8
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkWinGetPlatformId(void)
{
    return VER_PLATFORM_WIN32_NT;
}

/*
 *----------------------------------------------------------------------
 *
 * 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 *dummy,		/* Not used. */
    TCL_UNUSED(Tcl_Interp *),
    const char *screenName)	/* If NULL, use default string. */
{
    (void)dummy;

    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = winScreenName;
    }
    return screenName;
}

/*
428
429
430
431
432
433
434
435

436
437
438

439
440
441
442
443



444
445

446
447
448
449
450
451
452
453
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
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







-
+


-
+


-
-
-
+
+
+

-
+












-
+

-
-
+
+

-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+


-
-
+
+

-
+






-
+


















+
+












+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
+
+













-
-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







void
TkWinDisplayChanged(
    Display *display)
{
    HDC dc;
    Screen *screen;

    if (display == NULL || display->screens == NULL) {
    if (display == NULL || ScreenOfDisplay(display, 0) == NULL) {
	return;
    }
    screen = display->screens;
    screen = ScreenOfDisplay(display, 0);

    dc = GetDC(NULL);
    screen->width = GetDeviceCaps(dc, HORZRES);
    screen->height = GetDeviceCaps(dc, VERTRES);
    screen->mwidth = MulDiv(screen->width, 254,
    WidthOfScreen(screen) = GetDeviceCaps(dc, HORZRES);
    HeightOfScreen(screen) = GetDeviceCaps(dc, VERTRES);
    WidthMMOfScreen(screen) = MulDiv(WidthOfScreen(screen), 254,
	    GetDeviceCaps(dc, LOGPIXELSX) * 10);
    screen->mheight = MulDiv(screen->height, 254,
    HeightMMOfScreen(screen) = MulDiv(HeightOfScreen(screen), 254,
	    GetDeviceCaps(dc, LOGPIXELSY) * 10);

    /*
     * On windows, when creating a color bitmap, need two pieces of
     * 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);
    DefaultDepthOfScreen(screen) = GetDeviceCaps(dc, BITSPIXEL) * PTR2INT(screen->ext_data);

    if (screen->root_visual != NULL) {
	ckfree(screen->root_visual);
    if (DefaultVisualOfScreen(screen) != NULL) {
	ckfree(DefaultVisualOfScreen(screen));
    }
    screen->root_visual = (Visual *)ckalloc(sizeof(Visual));
    screen->root_visual->visualid = 0;
    DefaultVisualOfScreen(screen) = (Visual *)ckalloc(sizeof(Visual));
    DefaultVisualOfScreen(screen)->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;
	DefaultVisualOfScreen(screen)->map_entries = GetDeviceCaps(dc, SIZEPALETTE);
	DefaultVisualOfScreen(screen)->c_class = PseudoColor;
	DefaultVisualOfScreen(screen)->red_mask = 0x0;
	DefaultVisualOfScreen(screen)->green_mask = 0x0;
	DefaultVisualOfScreen(screen)->blue_mask = 0x0;
    } else if (DefaultDepthOfScreen(screen) == 4) {
	DefaultVisualOfScreen(screen)->c_class = StaticColor;
	DefaultVisualOfScreen(screen)->map_entries = 16;
    } else if (DefaultDepthOfScreen(screen) == 8) {
	DefaultVisualOfScreen(screen)->c_class = StaticColor;
	DefaultVisualOfScreen(screen)->map_entries = 256;
    } else if (DefaultDepthOfScreen(screen) == 12) {
	DefaultVisualOfScreen(screen)->c_class = TrueColor;
	DefaultVisualOfScreen(screen)->map_entries = 32;
	DefaultVisualOfScreen(screen)->red_mask = 0xf0;
	DefaultVisualOfScreen(screen)->green_mask = 0xf000;
	DefaultVisualOfScreen(screen)->blue_mask = 0xf00000;
    } else if (DefaultDepthOfScreen(screen) == 16) {
	DefaultVisualOfScreen(screen)->c_class = TrueColor;
	DefaultVisualOfScreen(screen)->map_entries = 64;
	DefaultVisualOfScreen(screen)->red_mask = 0xf8;
	DefaultVisualOfScreen(screen)->green_mask = 0xfc00;
	DefaultVisualOfScreen(screen)->blue_mask = 0xf80000;
    } else if (DefaultDepthOfScreen(screen) >= 24) {
	DefaultVisualOfScreen(screen)->c_class = TrueColor;
	DefaultVisualOfScreen(screen)->map_entries = 256;
	DefaultVisualOfScreen(screen)->red_mask = 0xff;
	DefaultVisualOfScreen(screen)->green_mask = 0xff00;
	DefaultVisualOfScreen(screen)->blue_mask = 0xff0000;
    }
    screen->root_visual->bits_per_rgb = screen->root_depth;
    DefaultVisualOfScreen(screen)->bits_per_rgb = DefaultDepthOfScreen(screen);
    ReleaseDC(NULL, dc);

    if (screen->cmap != None) {
	XFreeColormap(display, screen->cmap);
    if (DefaultColormapOfScreen(screen) != None) {
	XFreeColormap(display, DefaultColormapOfScreen(screen));
    }
    screen->cmap = XCreateColormap(display, None, screen->root_visual,
    DefaultColormapOfScreen(screen) = XCreateColormap(display, None, DefaultVisualOfScreen(screen),
	    AllocNone);
}

/*
 *----------------------------------------------------------------------
 *
 * TkpOpenDisplay/XkbOpenDisplay --
 * 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)
{
    Display *display;
    Screen *screen;
    TkWinDrawable *twdPtr;
    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 = ckalloc(sizeof(Display));
    memset(display, 0, sizeof(Display));
    display = XkbOpenDisplay((char *)display_name, NULL, NULL, NULL, NULL, NULL);

    display->display_name = ckalloc(strlen(display_name) + 1);
    strcpy(display->display_name, display_name);

    display->nscreens = 1;
    LastKnownRequestProcessed(display) = 1;
    display->qlen = 0;

    screen = ckalloc(sizeof(Screen));
    memset(screen, 0, sizeof(Screen));
    DisplayOfScreen(screen) = display;

    /*
     * Set up the root window.
     */

    twdPtr = ckalloc(sizeof(TkWinDrawable));
    if (twdPtr == NULL) {
	return NULL;
    }
    twdPtr->type = TWD_WINDOW;
    twdPtr->window.winPtr = NULL;
    twdPtr->window.handle = NULL;
    RootWindowOfScreen(screen) = (Window)twdPtr;

    /*
     * Note that these pixel values are not palette relative.
     */

    WhitePixelOfScreen(screen) = RGB(255, 255, 255);
    BlackPixelOfScreen(screen) = RGB(0, 0, 0);
    DefaultColormapOfScreen(screen) = 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 = ckalloc(sizeof(TkDisplay));
    memset(tsdPtr->winDisplay, 0, 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 --
 *
 *	Closes and deallocates a Display structure created with the
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
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







-
-
-
+
+
+

-
-
+
+

-
-
+
+

-
+







    }

    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 (ScreenOfDisplay(display, 0) != NULL) {
	if (DefaultVisualOfScreen(ScreenOfDisplay(display, 0)) != NULL) {
	    ckfree(DefaultVisualOfScreen(ScreenOfDisplay(display, 0)));
	}
	if (display->screens->root != None) {
	    ckfree((char *)display->screens->root);
	if (RootWindowOfScreen(ScreenOfDisplay(display, 0)) != None) {
	    ckfree(RootWindowOfScreen(ScreenOfDisplay(display, 0)));
	}
	if (display->screens->cmap != None) {
	    XFreeColormap(display, display->screens->cmap);
	if (DefaultColormapOfScreen(ScreenOfDisplay(display, 0)) != None) {
	    XFreeColormap(display, DefaultColormapOfScreen(ScreenOfDisplay(display, 0)));
	}
	ckfree(display->screens);
	ckfree(ScreenOfDisplay(display, 0));
    }
    ckfree(display);
}

/*
 *----------------------------------------------------------------------
 *
713
714
715
716
717
718
719
720
721


722
723
724
725
726
727
728
729
730
731
732
729
730
731
732
733
734
735


736
737
738



739
740
741
742
743
744
745







-
-
+
+

-
-
-







 *	Plays a sounds out the system speakers.
 *
 *----------------------------------------------------------------------
 */

int
XBell(
    Display *display,
    int percent)
    TCL_UNUSED(Display *),
    TCL_UNUSED(int))
{
    (void)display;
    (void)percent;

    MessageBeep(MB_OK);
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
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
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







-
+








-
+
















-
+














-
+







    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)) {
            if (Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
                result = 0;
	    } else {
	        result = 1;
	    }
	}
	break;

    default:
	if (!TkTranslateWinEvent(hwnd, message, wParam, lParam, &result)) {
	if (!Tk_TranslateWinEvent(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 --
 * 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
TkTranslateWinEvent(
Tk_TranslateWinEvent(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam,
    LRESULT *resultPtr)
{
    *resultPtr = 0;
914
915
916
917
918
919
920
921

922
923
924
925
926
927
928
927
928
929
930
931
932
933

934
935
936
937
938
939
940
941







-
+







    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));
	Tk_PointerEvent(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.
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030
1031







-
+








    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.serial = LastKnownRequestProcessed(winPtr->display)++;
    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;
1437
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448
1449
1450
1451
1450
1451
1452
1453
1454
1455
1456

1457
1458
1459
1460
1461
1462
1463
1464







-
+







    TkKeyEvent *xkey,
    UINT type)
{
    MSG msg;

    xkey->nbytes = 0;

    while ((xkey->nbytes < XMaxTransChars)
    while ((xkey->nbytes < sizeof(xkey->trans_chars))
	    && (PeekMessageA(&msg, NULL, type, type, PM_NOREMOVE) != 0)) {
	if (msg.message != type) {
	    break;
	}

	GetMessageA(&msg, NULL, type, type);

1515
1516
1517
1518
1519
1520
1521
1522

1523
1524
1525
1526
1527
1528
1529
1528
1529
1530
1531
1532
1533
1534

1535
1536
1537
1538
1539
1540
1541
1542







-
+








	return;
    }

    if (charsetInfo.ciACP == CP_UTF8) {
	strcpy(codepage, "utf-8");
    } else {
	sprintf(codepage, "cp%d", charsetInfo.ciACP);
	snprintf(codepage, sizeof(codepage), "cp%d", charsetInfo.ciACP);
    }

    if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) {
	/*
	 * The encoding is not supported by Tcl.
	 */

1659
1660
1661
1662
1663
1664
1665
1666

1667
1668
1669
1670
1671
1672
1673
1672
1673
1674
1675
1676
1677
1678

1679
1680
1681
1682
1683
1684
1685
1686







-
+







	 * 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.serial = LastKnownRequestProcessed(winPtr->display)++;
	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();
1697
1698
1699
1700
1701
1702
1703
























1704
1705
1706
1707
1708
1709
1710
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	}

	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
1742
1743
1744
1745
1746
1747
1748
1749

1750
1751
1752
1753

1754
1755
1756
1757
1758
1759
1760
1779
1780
1781
1782
1783
1784
1785

1786
1787
1788
1789

1790
1791
1792
1793
1794
1795
1796
1797







-
+



-
+







	msg = WM_MBUTTONDOWN;
	wparam = MK_MBUTTON;
	break;
    case Button3:
	msg = WM_RBUTTONDOWN;
	wparam = MK_RBUTTON;
	break;
    case Button8:
    case Button4:
	msg = WM_XBUTTONDOWN;
	wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1);
	break;
    case Button9:
    case Button5:
	msg = WM_XBUTTONDOWN;
	wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2);
	break;
    default:
	return 0;
    }

1949
1950
1951
1952
1953
1954
1955
1956

1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1986
1987
1988
1989
1990
1991
1992

1993
1994
1995

1996
1997
1998
1999
2000
2001
2002







-
+


-







 *	None.
 *
 *----------------------------------------------------------------------
 */

long
Tk_GetUserInactiveTime(
     Display *dpy)		/* Ignored on Windows */
     TCL_UNUSED(Display *))
{
    LASTINPUTINFO li;
    (void)dpy;

    li.cbSize = sizeof(li);
    if (!GetLastInputInfo(&li)) {
	return -1;
    }

    /*
1985
1986
1987
1988
1989
1990
1991
1992

1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2021
2022
2023
2024
2025
2026
2027

2028
2029
2030

2031
2032
2033
2034
2035
2036
2037







-
+


-







 *	to zero.
 *
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    Display *dpy)
    TCL_UNUSED(Display *))
{
    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;
Changes to win/ttkWinMonitor.c.
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
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[] = {
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
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65







-
+







	{ "SystemWindowText",		COLOR_WINDOWTEXT },
	{ NULL, 0 }
};

static void RegisterSystemColors(Tcl_Interp *interp)
{
    Ttk_ResourceCache cache = Ttk_GetResourceCache(interp);
    const SystemColorEntry *sysColor;
    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;
148
149
150
151
152
153
154
155

156
157
158
159
160
161
148
149
150
151
152
153
154

155
156
157
158
159
160
161







-
+






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);
    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
1
2
3
4
5
6
7

8
9
10
11
12
13
14
15







-
+







/* winTheme.c - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sf.net>
 */

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#endif

#include <tkWinInt.h>
#include "tkWinInt.h"

#ifndef DFCS_HOT	/* Windows 98/Me, Windows 2000/XP only */
#define DFCS_HOT 0
#endif

#include "ttk/ttkTheme.h"

50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101



102
103
104

105
106
107
108
109
110
111
112

113
114

115
116
117

118
119
120
121
122
123
124
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84

85
86
87
88
89
90
91
92
93
94
95
96
97
98



99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114

115
116
117

118
119
120
121
122
123
124
125







-
+




















-
+






-
+













-
-
-
+
+
+



+







-
+

-
+


-
+







    }
}

/*------------------------------------------------------------------------
 * +++ State tables for FrameControlElements.
 */

static const Ttk_StateTable checkbutton_statemap[] = { /* see also SF#1865898 */
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 const Ttk_StateTable pushbutton_statemap[] = {
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 const Ttk_StateTable arrow_statemap[] = {
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  */
    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 */
    unsigned cxId;		/* system metric ids for width/height... */
    unsigned cyId;		/* ... or size if FIXEDSIZE bit set */
    Ttk_StateTable *stateMap;	/* map Tk states to Win32 flags */
    Ttk_Padding margins;	/* additional placement padding */
} FrameControlElementData;

#define BASE_DIM    13
#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[] = {
static FrameControlElementData FrameControlElements[] = {
    { "Checkbutton.indicator",
	DFC_BUTTON, DFCS_BUTTONCHECK, FIXEDSIZE(13), FIXEDSIZE(13),
	DFC_BUTTON, DFCS_BUTTONCHECK, FIXEDSIZE(BASE_DIM), FIXEDSIZE(BASE_DIM),
	checkbutton_statemap, {0,0,4,0} },
    { "Radiobutton.indicator",
    	DFC_BUTTON, DFCS_BUTTONRADIO, FIXEDSIZE(13), FIXEDSIZE(13),
    	DFC_BUTTON, DFCS_BUTTONRADIO, FIXEDSIZE(BASE_DIM), FIXEDSIZE(BASE_DIM),
	checkbutton_statemap, {0,0,4,0} },
    { "uparrow",
    	DFC_SCROLL, DFCS_SCROLLUP, SM_CXVSCROLL, SM_CYVSCROLL,
	arrow_statemap, {0,0,0,0} },
    { "downarrow",
    	DFC_SCROLL, DFCS_SCROLLDOWN, SM_CXVSCROLL, SM_CYVSCROLL,
	arrow_statemap, {0,0,0,0} },
140
141
142
143
144
145
146
147
148






149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165






166
167
168
169
170
171
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196


197
198
199
200
201
202
203
204
205
206
207
208
209







210
211
212
213
214

215
216





217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255

256
257
258
259
260
261
262
263
264
265
266
267
268







269
270
271
272
273

274
275





276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

313
314

315
316

317
318

319
320
321
322

323
324





325
326
327
328

329
330
331
332
333
334
335
336
337
338
339
340
141
142
143
144
145
146
147


148
149
150
151
152
153
154
155
156
157



158
159
160
161
162
163
164
165
166


167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200


201
202
203
204
205
206









207
208
209
210
211
212
213
214
215
216
217
218
219


220
221
222
223
224
225
226
227
228
229
230


231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

259
260

261
262
263
264
265









266
267
268
269
270
271
272
273
274
275
276
277
278


279
280
281
282
283
284
285
286
287
288
289


290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318
319

320
321

322
323

324
325
326
327
328
329


330
331
332
333
334
335
336
337

338
339




340
341
342
343
344
345
346







-
-
+
+
+
+
+
+




-
-
-



+





-
-
+
+
+
+
+
+





-







-
+















-
-
+
+




-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+





+
-
-
+
+
+
+
+






-
-











-
+
















-
+

-
+




-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+





+
-
-
+
+
+
+
+






-
-









-
+


















-
+

-
+

-
+

-
+




+
-
-
+
+
+
+
+



-
+

-
-
-
-








    { 0,0,0,0,0,0, {0,0,0,0} }
};

/* ---------------------------------------------------------------------- */

static void FrameControlElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    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)
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State 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 = {
static 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" },
static Ttk_ElementOptionSpec BorderElementOptions[] = {
    { "-relief", TK_OPTION_RELIEF, Tk_Offset(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;

    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void BorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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 const Ttk_ElementOptionSpec FieldElementOptions[] = {
static Ttk_ElementOptionSpec FieldElementOptions[] = {
    { "-fieldbackground", TK_OPTION_BORDER,
    	offsetof(FieldElement,backgroundObj), "white" },
    	Tk_Offset(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;

    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void FieldElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
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 const Ttk_ElementOptionSpec ButtonBorderElementOptions[] = {
static Ttk_ElementOptionSpec ButtonBorderElementOptions[] = {
    { "-relief",TK_OPTION_RELIEF,
	offsetof(ButtonBorderElement,reliefObj), "flat" },
	Tk_Offset(ButtonBorderElement,reliefObj), "flat" },
    { "-highlightcolor",TK_OPTION_COLOR,
	offsetof(ButtonBorderElement,highlightColorObj), "black" },
	Tk_Offset(ButtonBorderElement,highlightColorObj), "black" },
    { "-default", TK_OPTION_ANY,
	offsetof(ButtonBorderElement,defaultStateObj), "disabled" },
	Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

static void ButtonBorderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_RAISED;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int 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:
348
349
350
351
352
353
354

355
356





357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
354
355
356
357
358
359
360
361


362
363
364
365
366
367
368
369

370
371
372
373

374
375
376
377
378
379
380







+
-
-
+
+
+
+
+



-
+



-







    cx += 2;
    cy += 2;

    *paddingPtr = Ttk_MakePadding(cx,cy,cx,cy);
}

static void ButtonBorderElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ButtonBorderElement *bd = (ButtonBorderElement *)elementRecord;
    int relief = TK_RELIEF_FLAT;
    Ttk_ButtonDefaultState defaultState = TTK_BUTTON_DEFAULT_DISABLED;
    int 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);
379
380
381
382
383
384
385


386
387
388
389
390
391



392
393
394
395
396

397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418







419
420
421
422


423
424


425
426
427
428



429
430
431
432
433


434
435
436
437
438

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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
388
389
390
391
392
393
394
395
396
397
398
399
400


401
402
403
404

405
406

407
408
409
410
411
412
413
414
415
416

417
418
419
420









421
422
423
424
425
426
427
428
429
430
431
432
433


434
435




436
437
438
439




440
441

442
443
444

445
446
447
448
449
450
451
452
453
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







+
+




-
-
+
+
+

-


-
+









-
+



-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+




+
+
-
-
+
+
-
-
-
-
+
+
+

-
-
-
-
+
+
-



-
+















-
+

-
+





+
-
-
+
+
+
-
-
-
-
+
+
+

-
-
+


-
+

-
-
-
+
+
-









-
+






-
+







    hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);

    rc = BoxToRect(b);
    DrawFrameControl(hdc, &rc,
	DFC_BUTTON,	/* classId */
	DFCS_BUTTONPUSH | Ttk_StateTableLookup(pushbutton_statemap, state));

    TkWinReleaseDrawableDC(d, hdc, &dcState);

    /* Draw focus ring:
     */
    if (state & TTK_STATE_FOCUS) {
	short int borderWidth = 3;	/* @@@ Use GetSystemMetrics?*/
	rc = BoxToRect(Ttk_PadBox(b, Ttk_UniformPadding(borderWidth)));
    	DrawFocusRect(hdc, &rc);
	b = Ttk_PadBox(b, Ttk_UniformPadding(borderWidth));
	TkWinDrawDottedRect(Tk_Display(tkwin), d, -1, b.x, b.y,
	    b.width, b.height);
    }
    TkWinReleaseDrawableDC(d, hdc, &dcState);
}

static const Ttk_ElementSpec ButtonBorderElementSpec = {
static Ttk_ElementSpec ButtonBorderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(ButtonBorderElement),
    ButtonBorderElementOptions,
    ButtonBorderElementSize,
    ButtonBorderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Focus element.
 * 	Draw dashed focus rectangle.
 * 	Draw dotted 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;

    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    *paddingPtr = Ttk_UniformPadding(1);
}

static void FocusElementDraw(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    Tk_Window tkwin,
    Drawable d,
{
    (void)dummy;
    (void)elementRecord;

    Ttk_Box b,
    Ttk_State state)
{
    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	HDC hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    	DrawFocusRect(hdc, &rc);
	TkWinDrawDottedRect(Tk_Display(tkwin), d, -1, b.x, b.y,
	    b.width, b.height);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }
}

static const Ttk_ElementSpec FocusElementSpec = {
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 const Ttk_ElementOptionSpec FillFocusElementOptions[] = {
static Ttk_ElementOptionSpec FillFocusElementOptions[] = {
    { "-focusfill", TK_OPTION_COLOR,
	offsetof(FillFocusElement,fillColorObj), "white" },
	Tk_Offset(FillFocusElement,fillColorObj), "white" },
    {NULL, TK_OPTION_BOOLEAN, 0, NULL}
};

	/* @@@ FIX THIS */
static void FillFocusElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
{
    FillFocusElement *focus = (FillFocusElement *)elementRecord;
    (void)dummy;

    Ttk_Box b,
    Ttk_State state)
{
    if (state & TTK_STATE_FOCUS) {
	RECT rc = BoxToRect(b);
	TkWinDCState dcState;
	FillFocusElement *focus = (FillFocusElement *)elementRecord;
	XColor *fillColor = Tk_GetColorFromObj(tkwin, focus->fillColorObj);
	GC gc = Tk_GCForColor(fillColor, d);
	HDC hdc;
	XFillRectangle(Tk_Display(tkwin), d, gc, b.x, b.y, b.width, b.height);

	XFillRectangle(Tk_Display(tkwin),d,gc, b.x,b.y,b.width,b.height);
	hdc = TkWinGetDrawableDC(Tk_Display(tkwin), d, &dcState);
    	DrawFocusRect(hdc, &rc);
	TkWinDrawDottedRect(Tk_Display(tkwin), d, -1, b.x, b.y,
	    b.width, b.height);
	TkWinReleaseDrawableDC(d, hdc, &dcState);
    }
}

/*
 * ComboboxFocusElement --
 * 	Read-only comboboxes have a filled focus ring, editable ones do not.
 */
static void ComboboxFocusElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    Drawable d, Ttk_Box b, Ttk_State state)
{
    if (state & TTK_STATE_READONLY) {
    	FillFocusElementDraw(clientData, elementRecord, tkwin, d, b, state);
    }
}

static const Ttk_ElementSpec ComboboxFocusElementSpec = {
static Ttk_ElementSpec ComboboxFocusElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(FillFocusElement),
    FillFocusElementOptions,
    FocusElementSize,
    ComboboxFocusElementDraw
};

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
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







-
-
+
+
+
+
+
+






-
-



















-
+















-
-
+
+




+
-
-
+
+
+
+
+


-
+
-
-
-

-
+










+
+
-
-
+
+
+
+




-
-










-
+
















-
-
+
+





+
-
-
+
+
+
+
+


-
+
-
-
-

-
+










+
+
-
-
+
+
+
+




-
-
-






-
+











+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+

+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





+
+
-
-
+
+
+
+




-
-
-





-
+







    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)
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
static 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"},
static Ttk_ElementOptionSpec ThumbElementOptions[] = {
    { "-orient", TK_OPTION_ANY, Tk_Offset(ThumbElement,orientObj),"horizontal"},
    { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void ThumbElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    ThumbElement *thumbPtr = (ThumbElement *)elementRecord;
    Ttk_Orient orient;
    int orient;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, thumbPtr->orientObj, &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(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State 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 = {
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 const Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-orient", TK_OPTION_ANY, offsetof(SliderElement,orientObj),
static Ttk_ElementOptionSpec SliderElementOptions[] = {
    { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj),
      "horizontal" },
      { NULL, TK_OPTION_BOOLEAN, 0, NULL }
};

static void SliderElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *elementRecord,
    TCL_UNUSED(Tk_Window),
    int *widthPtr,
    int *heightPtr,
    TCL_UNUSED(Ttk_Padding *))
{
    SliderElement *slider = (SliderElement *)elementRecord;
    Ttk_Orient orient;
    int orient;
    (void)dummy;
    (void)tkwin;
    (void)paddingPtr;

    TtkGetOrientFromObj(NULL, slider->orientObj, &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(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
static Ttk_ElementSpec SliderElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(SliderElement),
    SliderElementOptions,
    SliderElementSize,
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Notebook elements.
 */

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,TK_OPTION_BOOLEAN,0,0}
};

static void ClientElementSize(
    void *dummy, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
static void TabElementSize(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    TabElement *tab = (TabElement *)elementRecord;
    int borderWidth = 1;
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    (void)dummy;
    (void)elementRecord;
    (void)tkwin;
    (void)widthPtr;
    (void)heightPtr;


    Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth);
    *paddingPtr = Ttk_UniformPadding((short)borderWidth);

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    TCL_UNUSED(void *), /* clientData */
    void *elementRecord,
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    TabElement *tab = (TabElement *)elementRecord;
    Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj);
    XPoint pts[6];
    int cut = 2;
    Display *disp = Tk_Display(tkwin);
    int borderWidth = 1;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    if (state & TTK_STATE_SELECTED) {
	/*
	 * Draw slightly outside of the allocated parcel,
	 * to overwrite the client area border.
	 */
	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		b.height += 2;
		break;
	    case TTK_STICK_N:
		b.height += 2; b.y -= 2;
		break;
	    case TTK_STICK_E:
		b.width += 2;
		break;
	    case TTK_STICK_W:
		b.width += 2; b.x -= 2;
		break;
	}
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    pts[0].x = b.x;  pts[0].y = b.y + b.height-1;
	    pts[1].x = b.x;  pts[1].y = b.y + cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y + b.height;
	    break;
	case TTK_STICK_N:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x;  pts[1].y = b.y + b.height-1 - cut;
	    pts[2].x = b.x + cut;  pts[2].y = b.y + b.height-1;
	    pts[3].x = b.x + b.width-1 - cut;  pts[3].y = b.y + b.height-1;
	    pts[4].x = b.x + b.width-1;  pts[4].y = b.y + b.height-1 - cut;
	    pts[5].x = b.x + b.width-1;  pts[5].y = b.y-1;
	    break;
	case TTK_STICK_E:
	    pts[0].x = b.x + b.width-1;  pts[0].y = b.y;
	    pts[1].x = b.x + cut;  pts[1].y = b.y;
	    pts[2].x = b.x;  pts[2].y = b.y + cut;
	    pts[3].x = b.x;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x + b.width;  pts[5].y = b.y + b.height-1;
	    break;
	case TTK_STICK_W:
	    pts[0].x = b.x;  pts[0].y = b.y;
	    pts[1].x = b.x + b.width-1 - cut;  pts[1].y = b.y;
	    pts[2].x = b.x + b.width-1;  pts[2].y = b.y + cut;
	    pts[3].x = b.x + b.width-1;  pts[3].y = b.y + b.height-1 - cut;
	    pts[4].x = b.x + b.width-1 - cut;  pts[4].y = b.y + b.height-1;
	    pts[5].x = b.x-1;  pts[5].y = b.y + b.height-1;
	    break;
    }

    XFillPolygon(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC),
	    pts, 6, Convex, CoordModeOrigin);

    Tk_GetPixelsFromObj(NULL, tkwin, tab->borderWidthObj, &borderWidth);
    while (borderWidth--) {
	XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC),
		pts, 4, CoordModeOrigin);
	XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC),
		pts+3, 3, CoordModeOrigin);

	switch (nbTabsStickBit) {
	    default:
	    case TTK_STICK_S:
		++pts[0].x;  ++pts[1].x;  ++pts[2].y;
		++pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_N:
		++pts[0].x;  ++pts[1].x;  --pts[2].y;
		--pts[3].y;  --pts[4].x;  --pts[5].x;
		break;
	    case TTK_STICK_E:
		++pts[0].y;  ++pts[1].y;  ++pts[2].x;
		++pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	    case TTK_STICK_W:
		++pts[0].y;  ++pts[1].y;  --pts[2].x;
		--pts[3].x;  --pts[4].y;  --pts[5].y;
		break;
	}
    }
}

static Ttk_ElementSpec TabElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(TabElement),
    TabElementOptions,
    TabElementSize,
    TabElementDraw
};

static void ClientElementSize(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    TCL_UNUSED(Tk_Window),
    TCL_UNUSED(int *), /* widthPtr */
    TCL_UNUSED(int *), /* heightPtr */
    Ttk_Padding *paddingPtr)
{
    paddingPtr->left = paddingPtr->right = GetSystemMetrics(SM_CXEDGE);
    paddingPtr->top = paddingPtr->bottom = GetSystemMetrics(SM_CYEDGE);
}

static void ClientElementDraw(
    TCL_UNUSED(void *), /* clientData */
    TCL_UNUSED(void *), /* elementRecord */
    void *dummy, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    TCL_UNUSED(Ttk_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 = {
static Ttk_ElementSpec ClientElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    ClientElementSize,
    ClientElementDraw
};

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
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







-
-
+
+
+
+



-



















+













	    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)
MODULE_SCOPE int
TtkWinTheme_Init(
    Tcl_Interp *interp,
    TCL_UNUSED(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;
    }

    Ttk_RegisterElementSpec(themePtr, "border", &BorderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Button.border",
	&ButtonBorderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "field", &FieldElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "focus", &FocusElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Combobox.focus",
    	&ComboboxFocusElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "thumb", &ThumbElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "slider", &SliderElementSpec, NULL);
    Ttk_RegisterElementSpec(themePtr, "Scrollbar.trough", &TroughElementSpec,
    	TroughClientDataInit(interp));

    Ttk_RegisterElementSpec(themePtr, "tab", &TabElementSpec, NULL);
    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;
}

Changes to win/ttkWinXPTheme.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
1
2
3
4



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27




-
-
-
+
+
+










+
+
-
+







/*
 * Tk theme engine which uses the Windows XP "Visual Styles" API
 * Adapted from Georgios Petasis' XP theme patch.
 *
 * Copyright (c) 2003 by Georgios Petasis, petasis@iit.demokritos.gr.
 * Copyright (c) 2003 by Joe English
 * Copyright (c) 2003 by Pat Thoyts
 * Copyright (c) 2003 Georgios Petasis, petasis@iit.demokritos.gr.
 * Copyright (c) 2003 Joe English
 * Copyright (c) 2003 Pat Thoyts
 *
 * 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://msdn.microsoft.com/library/en-us/
 *  	shellcc/platform/commctls/userex/refentry.asp >
 */

#define WINVER 0x0501	/* Requires Windows XP APIs */

#include <tkWinInt.h>
#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>
33
34
35
36
37
38
39




40
41
42
43
44
45
46
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52







+
+
+
+








typedef HTHEME  (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd,
		 LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme,
                 HDC hdc, int iPartId, int iStateId, const RECT *pRect,
                 OPTIONAL const RECT *pClipRect);
typedef HRESULT (STDAPICALLTYPE DrawThemeEdgeProc)(HTHEME hTheme,
		 HDC hdc, int iPartId, int iStateId, const RECT *pDestRect,
		 unsigned int uEdge, unsigned int uFlags,
		 OPTIONAL RECT *pContentRect);
typedef HRESULT	(STDAPICALLTYPE GetThemePartSizeProc)(HTHEME,HDC,
		 int iPartId, int iStateId,
		 RECT *prc, enum THEMESIZE eSize, SIZE *psz);
typedef int     (STDAPICALLTYPE GetThemeSysSizeProc)(HTHEME,int);
/* GetThemeTextExtent and DrawThemeText only used with BROKEN_TEXT_ELEMENT */
typedef HRESULT (STDAPICALLTYPE GetThemeTextExtentProc)(HTHEME hTheme, HDC hdc,
		 int iPartId, int iStateId, LPCWSTR pszText, int iCharCount,
54
55
56
57
58
59
60

61
62
63
64
65
66
67
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74







+







typedef struct
{
    OpenThemeDataProc			*OpenThemeData;
    CloseThemeDataProc			*CloseThemeData;
    GetThemePartSizeProc		*GetThemePartSize;
    GetThemeSysSizeProc			*GetThemeSysSize;
    DrawThemeBackgroundProc		*DrawThemeBackground;
    DrawThemeEdgeProc			*DrawThemeEdge;
    DrawThemeTextProc		        *DrawThemeText;
    GetThemeTextExtentProc		*GetThemeTextExtent;
    IsThemeActiveProc			*IsThemeActive;
    IsAppThemedProc			*IsAppThemed;

    HWND                                stubWindow;
} XPThemeProcs;
107
108
109
110
111
112
113

114
115
116
117
118
119
120
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128







+







	(0 != (procs->name = (name ## Proc *)(void *)GetProcAddress(handle, #name) ))

	if (   LOADPROC(OpenThemeData)
	    && LOADPROC(CloseThemeData)
	    && LOADPROC(GetThemePartSize)
	    && LOADPROC(GetThemeSysSize)
	    && LOADPROC(DrawThemeBackground)
	    && LOADPROC(DrawThemeEdge)
	    && LOADPROC(GetThemeTextExtent)
	    && LOADPROC(DrawThemeText)
	    && LOADPROC(IsThemeActive)
	    && LOADPROC(IsAppThemed)
	)
	{
	    return procs;
136
137
138
139
140
141
142
143



144
145
146
147
148
149
150
151
152
153
154
155
144
145
146
147
148
149
150

151
152
153
154
155
156
157

158
159
160
161
162
163
164







-
+
+
+




-







{
    XPThemeData *themeData = (XPThemeData *)clientData;
    FreeLibrary(themeData->hlibrary);
    ckfree(clientData);
}

static int
XPThemeEnabled(Ttk_Theme theme, void *clientData)
XPThemeEnabled(
    TCL_UNUSED(Ttk_Theme),
    void *clientData)
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    int active = themeData->procs->IsThemeActive();
    int themed = themeData->procs->IsAppThemed();
    (void)theme;

    return (active && themed);
}

/*
 * BoxToRect --
 * 	Helper routine.  Returns a RECT data structure.
164
165
166
167
168
169
170
171

172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
173
174
175
176
177
178
179

180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358







-
+




-
+











-
+


















-
+
















-
+








-
+














-
+










-
+










-
+











-
+







-
+







-
+







-
+







-
+







-
+










-
+








-
+







    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} };
static Ttk_StateTable null_statemap[] = { {0,0,0} };

/*
 * Pushbuttons (Tk: "Button")
 */
static const Ttk_StateTable pushbutton_statemap[] =
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 const Ttk_StateTable checkbox_statemap[] =
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 const Ttk_StateTable radiobutton_statemap[] =
static 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[] =
static Ttk_StateTable groupbox_statemap[] =
{
{GBS_DISABLED,	TTK_STATE_DISABLED, 0},
{GBS_NORMAL,	0,0 }
};

/*
 * Edit fields (tk: "entry")
 */
static const Ttk_StateTable edittext_statemap[] =
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 const Ttk_StateTable combotext_statemap[] =
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 const Ttk_StateTable combobox_statemap[] = {
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 const Ttk_StateTable toolbutton_statemap[] =  {
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 const Ttk_StateTable scrollbar_statemap[] =
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 const Ttk_StateTable uparrow_statemap[] =
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 const Ttk_StateTable downarrow_statemap[] =
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 const Ttk_StateTable leftarrow_statemap[] =
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 const Ttk_StateTable rightarrow_statemap[] =
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 const Ttk_StateTable spinbutton_statemap[] =
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 const Ttk_StateTable scale_statemap[] =
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 const Ttk_StateTable tabitem_statemap[] =
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
379
380
381
382
383
384
385

386
387
388
389

390
391
392
393
394
395
396
397







-
+



-
+







 *	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;
    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_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 */
488
489
490
491
492
493
494
495
496






497
498
499
500
501
502
503
504
505
506
507
508
497
498
499
500
501
502
503


504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520







-
-
+
+
+
+
+
+




-







 * +++ Generic element implementation.
 *
 * Used for elements which are handled entirely by the XP Theme API,
 * such as radiobutton and checkbutton indicators, scrollbar arrows, etc.
 */

static void GenericElementSize(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    ElementData *elementData = (ElementData *)clientData;
    HRESULT result;
    SIZE size;
    (void)elementRecord;

    if (!InitElementData(elementData, tkwin, 0))
	return;

    if (!(elementData->info->flags & IGNORE_THEMESIZE)) {
	result = elementData->procs->GetThemePartSize(
	    elementData->hTheme,
525
526
527
528
529
530
531
532
533






534
535
536
537
538
539
540
541
542
543
544
537
538
539
540
541
542
543


544
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559







-
-
+
+
+
+
+
+



-







    if (elementData->info->flags & PAD_MARGINS) {
	*widthPtr += Ttk_PaddingWidth(elementData->info->padding);
	*heightPtr += Ttk_PaddingHeight(elementData->info->padding);
    }
}

static void GenericElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ElementData *elementData = (ElementData *)clientData;
    RECT rc;
    (void)elementRecord;

    if (!InitElementData(elementData, tkwin, d)) {
	return;
    }

    if (elementData->info->flags & PAD_MARGINS) {
    	b = Ttk_PadBox(b, elementData->info->padding);
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







-
+







	Ttk_StateTableLookup(elementData->info->statemap, state),
	&rc,
	NULL/*pContentRect*/);

    FreeElementData(elementData);
}

static const Ttk_ElementSpec GenericElementSpec =
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
607
608
609
610
611
612
613

614
615
616
617
618
619
620
621







-
+







	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 = {
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
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
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







-
+













-
-
+
+
+
+
+
+




-

















-
+







    GenericSizedElementSize(clientData, elementRecord, tkwin,
	widthPtr, heightPtr, paddingPtr);

    /* force the arrow button height to half size */
    *heightPtr /= 2;
}

static const Ttk_ElementSpec SpinboxArrowElementSpec = {
static Ttk_ElementSpec SpinboxArrowElementSpec = {
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    SpinboxArrowElementSize,
    GenericElementDraw
};

/*----------------------------------------------------------------------
 * +++ Scrollbar thumb element.
 *     Same as a GenericElement, but don't draw in the disabled state.
 */

static void ThumbElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    ElementData *elementData = (ElementData *)clientData;
    unsigned stateId = Ttk_StateTableLookup(elementData->info->statemap, state);
    RECT rc = BoxToRect(b);
    (void)elementRecord;

    /*
     * Don't draw the thumb if we are disabled.
     */
    if (state & TTK_STATE_DISABLED)
	return;

    if (!InitElementData(elementData, tkwin, d))
	return;

    elementData->procs->DrawThemeBackground(elementData->hTheme,
	elementData->hDC, elementData->info->partId, stateId,
	&rc, NULL);

    FreeElementData(elementData);
}

static const Ttk_ElementSpec ThumbElementSpec =
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
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724







-
+







    if (elementData->info->partId == PP_CHUNK) {
    	*widthPtr *= nBars;
    } else if (elementData->info->partId == PP_CHUNKVERT) {
    	*heightPtr *= nBars;
    }
}

static const Ttk_ElementSpec PbarElementSpec =
static Ttk_ElementSpec PbarElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    PbarElementSize,
    GenericElementDraw
};
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
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
+
+
+
+
+
+

+
+


+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+




-
+












-
+






-
+







-
+







-
+






-
+







 *	tab is exactly at the right edge of the notebook, but
 *	not if it's simply the rightmost tab.  This information
 * 	is not available.
 *
 *	The TIS_* and TILES_* definitions are identical, so
 * 	we can use the same statemap no matter what the partId.
 */

static void TabElementSize(
    void *clientData,
    void *elementRecord,
    Tk_Window tkwin,
    int *widthPtr,
    int *heightPtr,
    Ttk_Padding *paddingPtr)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    GenericElementSize(clientData, elementRecord, tkwin,
    	widthPtr, heightPtr, paddingPtr);

    *paddingPtr = Ttk_UniformPadding(3);
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    paddingPtr->bottom = 0;
	    break;
	case TTK_STICK_N:
	    paddingPtr->top = 0;
	    break;
	case TTK_STICK_E:
	    paddingPtr->right = 0;
	    break;
	case TTK_STICK_W:
	    paddingPtr->left = 0;
	    break;
    }
}

static void TabElementDraw(
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, unsigned int state)
    void *clientData,
    TCL_UNUSED(void *), /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S;
    TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr;
    ElementData *elementData = (ElementData *)clientData;
    int partId = elementData->info->partId;
    int isSelected = (state & TTK_STATE_SELECTED);
    int stateId = Ttk_StateTableLookup(elementData->info->statemap, state);
    RECT rc = BoxToRect(b);
    (void)elementRecord;
    RECT rc;

    if (mainInfoPtr != NULL) {
	nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit;
    }

    /*
     * Correct the members of b if needed
     */
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    break;
	case TTK_STICK_N:
	    b.y -= isSelected ? 0 : 1; b.height -= isSelected ? 1 : 0;
	    break;
	case TTK_STICK_E:
	    b.width -= isSelected ? 1 : 0;
	    break;
	case TTK_STICK_W:
	    b.x -= isSelected ? 1 : 2; b.width -= isSelected ? 1 : 0;
	    break;
    }

    rc = BoxToRect(b);

    if (!InitElementData(elementData, tkwin, d))
	return;

    if (nbTabsStickBit == TTK_STICK_S) {
    if (state & TTK_STATE_USER1)
	partId = TABP_TABITEMLEFTEDGE;
    elementData->procs->DrawThemeBackground(
	elementData->hTheme, elementData->hDC, partId,
	Ttk_StateTableLookup(elementData->info->statemap, state), &rc, NULL);
	if (state & TTK_STATE_USER1) {
	    partId = TABP_TABITEMLEFTEDGE;
	}

	/*
	 * Draw the border and fill into rc
	 */
	elementData->procs->DrawThemeBackground(
	    elementData->hTheme, elementData->hDC, partId, stateId, &rc, NULL);
    } else {
	/*
	 * Draw the fill but no border into rc
	 */
	RECT rc2 = rc;
	--rc2.top; --rc2.left; ++rc2.bottom; ++rc2.right;
	elementData->procs->DrawThemeBackground(
	    elementData->hTheme, elementData->hDC, partId, stateId, &rc2, &rc);
    }

    /*
     * Draw a flat border at 3 edges
     */
    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    break;
	case TTK_STICK_N:
	    elementData->procs->DrawThemeEdge(
		elementData->hTheme, elementData->hDC, partId, stateId, &rc,
		BDR_RAISEDINNER, BF_FLAT|BF_LEFT|BF_RIGHT|BF_BOTTOM, NULL);
	    break;
	case TTK_STICK_E:
	    elementData->procs->DrawThemeEdge(
		elementData->hTheme, elementData->hDC, partId, stateId, &rc,
		BDR_RAISEDINNER, BF_FLAT|BF_LEFT|BF_TOP|BF_BOTTOM, NULL);
	    break;
	case TTK_STICK_W:
	    elementData->procs->DrawThemeEdge(
		elementData->hTheme, elementData->hDC, partId, stateId, &rc,
		BDR_RAISEDINNER, BF_FLAT|BF_TOP|BF_RIGHT|BF_BOTTOM, NULL);
	    break;
    }

    FreeElementData(elementData);
}

static const Ttk_ElementSpec TabElementSpec =
static Ttk_ElementSpec TabElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TabElementSize,
    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[] =
static 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[] =
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 const Ttk_StateTable tvpglyph_statemap[] =
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)
    Drawable d, Ttk_Box b, Ttk_State state)
{
    if (!(state & TTK_STATE_LEAF)) {
        GenericElementDraw(clientData,elementRecord,tkwin,d,b,state);
    }
}

static const Ttk_ElementSpec TreeIndicatorElementSpec =
static Ttk_ElementSpec TreeIndicatorElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(NullElement),
    TtkNullElementOptions,
    GenericElementSize,
    TreeIndicatorElementDraw
};
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
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







-
+

-
+












-
+





-
+








-
+















-
-
+
+






-
+





-
+








-
+







-
+







    Tcl_Obj *textObj;
    Tcl_Obj *fontObj;
} TextElement;

static const Ttk_ElementOptionSpec TextElementOptions[] =
{
    { "-text", TK_OPTION_STRING,
	offsetof(TextElement,textObj), "" },
	Tk_Offset(TextElement,textObj), "" },
    { "-font", TK_OPTION_FONT,
	offsetof(TextElement,fontObj), DEFAULT_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;
    const char *src;
    TkSizeT len;
    int len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, 0))
	return;

    src = TkGetStringFromObj(element->textObj, &len);
    src = Tcl_GetStringFromObj(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,
	    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)
    void *clientData, void *elementRecord, Tk_Window tkwin,
    Drawable d, Ttk_Box b, Ttk_State state)
{
    TextElement *element = elementRecord;
    ElementData *elementData = clientData;
    RECT rc = BoxToRect(b);
    HRESULT hr = S_OK;
    const char *src;
    TkSizeT len;
    int len;
    Tcl_DString ds;

    if (!InitElementData(elementData, tkwin, d))
	return;

    src = TkGetStringFromObj(element->textObj, &len);
    src = Tcl_GetStringFromObj(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,
	    DT_LEFT /* | DT_BOTTOM | DT_NOPREFIX */,
	    (state & TTK_STATE_DISABLED) ? DTT_GRAYED : 0,
	    &rc);

    Tcl_DStringFree(&ds);
    FreeElementData(elementData);
}

static const Ttk_ElementSpec TextElementSpec =
static Ttk_ElementSpec TextElementSpec =
{
    TK_STYLE_VERSION_2,
    sizeof(TextElement),
    TextElementOptions,
    TextElementSize,
    TextElementDraw
};
956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1096







-
+







 */

#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[] = {
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",
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
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







-
+





-
+


-
+


















-
+





-
+
+









-
-
+
+







    Ttk_Theme theme,
    const char *elementName,
    int objc,
    Tcl_Obj *const objv[])
{
    XPThemeData *themeData = (XPThemeData *)clientData;
    ElementInfo *elementPtr = NULL;
    ClientData elementData;
    void *elementData;
    LPCWSTR className;
    int partId = 0;
    Ttk_StateTable *stateTable;
    Ttk_Padding pad = {0, 0, 0, 0};
    int flags = 0;
    TkSizeT length = 0;
    int length = 0;
    char *name;
    LPWSTR wname;
    const Ttk_ElementSpec *elementSpec = &GenericElementSpec;
    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);
    name = Tcl_GetStringFromObj(objv[0], &length);
    Tcl_DStringInit(&classBuf);
    className = Tcl_UtfToWCharDString(name, length, &classBuf);

    /* flags or padding */
    if (objc > 3) {
	int i = 3, option = 0;
	int i = 3;
	int 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)
	    if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
		    "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;
1211
1212
1213
1214
1215
1216
1217

1218

1219
1220
1221
1222
1223
1224
1225
1338
1339
1340
1341
1342
1343
1344
1345

1346
1347
1348
1349
1350
1351
1352
1353







+
-
+







	    }
	}
    }

    /* convert a statemap into a state table */
    if (objc > 2) {
	Tcl_Obj **specs;
	int n, j, count;
	int n,j,count, status = TCL_OK;
	int 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};
1272
1273
1274
1275
1276
1277
1278

1279

1280
1281
1282
1283
1284
1285
1286
1400
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
1415







+
-
+







    return TCL_ERROR;
}

/*----------------------------------------------------------------------
 * +++ Initialization routine:
 */

MODULE_SCOPE int
MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd)
TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd)
{
    XPThemeData *themeData;
    XPThemeProcs *procs;
    HINSTANCE hlibrary;
    Ttk_Theme themePtr, parentPtr, vistaPtr;
    const ElementInfo *infoPtr;

1322
1323
1324
1325
1326
1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461
1462
1463
1464
1465







-
+







	}
    }

    /*
     * New elements:
     */
    for (infoPtr = ElementInfoTable; infoPtr->elementName != 0; ++infoPtr) {
	ClientData clientData = NewElementData(procs, infoPtr);
	void *clientData = NewElementData(procs, infoPtr);
	Ttk_RegisterElementSpec(
	    themePtr, infoPtr->elementName, infoPtr->elementSpec, clientData);
	Ttk_RegisterCleanup(interp, clientData, DestroyElementData);
    }

    Ttk_RegisterElementSpec(themePtr, "Scale.trough", &ttkNullElementSpec, 0);

Changes to win/winMain.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
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34





35
36
37
38
39
40
41
42
43
44
45
46



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86







+
+
+
+









-
-
-
-
-
+
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+


+
+
+




















+
+
+
-
+
+







#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 TCL_MAJOR_VERSION < 9 && TCL_MINOR_VERSION < 7
#   define Tcl_LibraryInitProc Tcl_PackageInitProc
#   define Tcl_StaticLibrary Tcl_StaticPackage
#endif

#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 */
extern Tcl_LibraryInitProc Tktest_Init;
#endif /* TK_TEST */

#if !defined(TCL_USE_STATIC_PACKAGES)
#   if TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 6
#	define TCL_USE_STATIC_PACKAGES 1
#   else
#	define TCL_USE_STATIC_PACKAGES 0
#   endif
#endif

#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
extern Tcl_PackageInitProc Registry_Init;
extern Tcl_PackageInitProc Dde_Init;
extern Tcl_PackageInitProc Dde_SafeInit;
extern Tcl_LibraryInitProc Registry_Init;
extern Tcl_LibraryInitProc Dde_Init;
extern Tcl_LibraryInitProc Dde_SafeInit;
#endif

#ifdef __cplusplus
}
#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
#   ifdef __cplusplus
#	define MODULE_SCOPE extern "C"
#   else
#   define MODULE_SCOPE extern
#	define MODULE_SCOPE extern
#   endif
#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()
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
167
168
169
170
171
172
173



174
175
176
177
178
179
180







-
-
-







	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. */
}

/*
186
187
188
189
190
191
192











193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231












232
233
234
235

236
237
238
239
240
241
242
243







+
+
+
+
+
+
+
+
+
+
+



-
+











-
-
-
-
-
-
-
-
-
-
-
-




-
+







int
Tcl_AppInit(
    Tcl_Interp *interp)		/* Interpreter for application. */
{
    if ((Tcl_Init)(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
#if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES
    if (Registry_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Registry", Registry_Init, 0);

    if (Dde_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticLibrary(interp, "Dde", Dde_Init, Dde_SafeInit);
#endif
    if (Tk_Init(interp) == TCL_ERROR) {
	return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
    Tcl_StaticLibrary(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);
    Tcl_StaticLibrary(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) {
Added win/x86_64-w64-mingw32-nmakehlp.exe.

cannot compute difference between binary files

Changes to xlib/X11/DECkeysym.h.
48
49
50
51
52
53
54
55
56
57
58
59
60
61







62
63
64
65

48
49
50
51
52
53
54







55
56
57
58
59
60
61
62
63
64

65







-
-
-
-
-
-
-
+
+
+
+
+
+
+



-
+
/*
 * 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
#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 */
#define DXK_Remove                   0x1000ff00  /* Remove */
Changes to xlib/X11/HPkeysym.h.
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84























85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129








































130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156



















157
158

159
160
161
162



163
164
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61























62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89








































90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137



















138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

158
159



160
161
162
163
164







-
+












-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+

-
-
-
+
+
+


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
TO THIS SOFTWARE, 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
#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  /* deprecated alias for hpYdiaeresis */
#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
#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
#define XK_Reset                     0x1000ff6c  /* deprecated alias for hpReset */
#define XK_System                    0x1000ff6d  /* deprecated alias for hpSystem */
#define XK_User                      0x1000ff6e  /* deprecated alias for hpUser */
#define XK_ClearLine                 0x1000ff6f  /* deprecated alias for hpClearLine */
#define XK_InsertLine                0x1000ff70  /* deprecated alias for hpInsertLine */
#define XK_DeleteLine                0x1000ff71  /* deprecated alias for hpDeleteLine */
#define XK_InsertChar                0x1000ff72  /* deprecated alias for hpInsertChar */
#define XK_DeleteChar                0x1000ff73  /* deprecated alias for hpDeleteChar */
#define XK_BackTab                   0x1000ff74  /* deprecated alias for hpBackTab */
#define XK_KP_BackTab                0x1000ff75  /* deprecated alias for hpKP_BackTab */
#define XK_Ext16bit_L                0x1000ff76  /* deprecated */
#define XK_Ext16bit_R                0x1000ff77  /* deprecated */
#define XK_mute_acute                0x100000a8  /* deprecated alias for hpmute_acute */
#define XK_mute_grave                0x100000a9  /* deprecated alias for hpmute_grave */
#define XK_mute_asciicircum          0x100000aa  /* deprecated alias for hpmute_asciicircum */
#define XK_mute_diaeresis            0x100000ab  /* deprecated alias for hpmute_diaeresis */
#define XK_mute_asciitilde           0x100000ac  /* deprecated alias for hpmute_asciitilde */
#define XK_lira                      0x100000af  /* deprecated alias for hplira */
#define XK_guilder                   0x100000be  /* deprecated alias for hpguilder */
#ifndef XK_Ydiaeresis
#define XK_Ydiaeresis           0x100000ee
#define XK_Ydiaeresis                0x100000ee  /* deprecated */
#endif
#define XK_IO                   0x100000ee
#define XK_longminus            0x100000f6
#define XK_block                0x100000fc
#define XK_IO                        0x100000ee  /* deprecated alias for hpYdiaeresis */
#define XK_longminus                 0x100000f6  /* deprecated alias for hplongminus */
#define XK_block                     0x100000fc  /* deprecated alias for hpblock */

#endif /* _HPKEYSYM_H */
Changes to xlib/X11/Sunkeysym.h.
1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+







/*
 * Copyright (c) 1991, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1991, Oracle and/or its affiliates.
 *
 * 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:
46
47
48
49
50
51
52
53
54
55
56
57
58






59
60
61
62
63
64
65


66
67
68


69
70
71
72
73
74
75


76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97










98
99
100
101
102
103
104
105
106








46
47
48
49
50
51
52






53
54
55
56
57
58
59
60
61
62
63


64
65
66


67
68
69
70
71
72
73


74
75
76
77
78
79
80


81
82
83
84
85
86
87










88
89
90
91
92
93
94
95
96
97
98








99
100
101
102
103
104
105
106







-
-
-
-
-
-
+
+
+
+
+
+





-
-
+
+

-
-
+
+





-
-
+
+





-
-
+
+





-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

***********************************************************/

/*
 * 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
#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_F36                    0x1005ff10  /* Labeled F11 */
#define SunXK_F37                    0x1005ff11  /* Labeled F12 */

#define SunXK_Sys_Req   	0x1005FF60
#define SunXK_Print_Screen	0x0000FF61	/* Same as XK_Print */
#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 */
#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 */
#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_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
#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.
48
49
50
51
52
53
54





55
56
57








58


59



60

61




























62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88


89
90
91
92
93

94





95
96
97
98
99
100
101
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120









121
122
123


124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143







+
+
+
+
+



+
+
+
+
+
+
+
+
-
+
+

+
+
+
-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+














-
-
-
-
-
-
-
-
-
+


-
-
+
+





+
-
+
+
+
+
+







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 */

/*
 * _XSERVER64 must ONLY be defined when compiling X server sources on
 * systems where unsigned long is not 32 bits, must NOT be used in
 * client or library code.
 */
#ifndef _XSERVER64
#  ifndef _XTYPEDEF_XID
#    define _XTYPEDEF_XID
#ifdef _WIN64
#    ifdef _WIN64
#      ifdef _MSC_VER
typedef unsigned __int64 XID;
#      else
typedef unsigned long long XID;
#      endif
#else
#    else
typedef unsigned long XID;
#    endif
#  endif
#  ifndef _XTYPEDEF_MASK
#    define _XTYPEDEF_MASK
typedef unsigned long Mask;
#  endif
#  ifndef _XTYPEDEF_ATOM
#    define _XTYPEDEF_ATOM
typedef unsigned long Atom;		/* Also in Xdefs.h */
#  endif
typedef unsigned long VisualID;
typedef unsigned long Time;
#else
#  include <X11/Xmd.h>
#  ifndef _XTYPEDEF_XID
#    define _XTYPEDEF_XID
typedef CARD32 XID;
#  endif
#  ifndef _XTYPEDEF_MASK
#    define _XTYPEDEF_MASK
typedef CARD32 Mask;
#  endif
#  ifndef _XTYPEDEF_ATOM
#    define _XTYPEDEF_ATOM
typedef CARD32 Atom;
#  endif
typedef CARD32 VisualID;
typedef CARD32 Time;
#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
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. */
				 * defined as an unsigned char, which wouldn't
				 * be big enough. */

/*****************************************************************
 * RESERVED RESOURCE AND CONSTANT DEFINITIONS
 *****************************************************************/

#ifndef _WIN32
/* #define None              0L      See bug [9e31fd9449] and below */
#   define None              0L      /* See bug [9e31fd9449] and below */
#else
/* Perl-Tk expects None to be a macro. See ticket [593eb0227c] */
#   define None              None    /* uses the enum 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
227
228
229
230
231
232
233


234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264







-
-
+







+
-
+
+
+
+
+







+
-
+
+







#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 # */
#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 */
#   define ControlMask		(1<<2) /* See bug [9e31fd9449] and below */
#else
/* Perl-Tk expects ControlMask to be a macro. See ticket [593eb0227c] */
#   define ControlMask		ControlMask /* uses the enum 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) };
enum { 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
690
691
692
693
694
695
696
697





698
738
739
740
741
742
743
744
745
746
747
748
749
750
751








+
+
+
+
+

#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 */
Changes to 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
















































































































































































































































































1
2
3

4
5


6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27






28
29
30
31
32
33
34
35
36
37













38
39
40
41
42
43
44
45
46
47
48
49
50
51
52









53
54
55
56
57
58
59
60
61
62
63










































64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

























































107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164






165
166
167
168
169
170
171




172
173
174
175
176












177
178
179
180
181
182
183
184
185
186
187
188
189




190
191
192
193
194





195
196
197
198
199
200

201
202

203
204


205
206
207

208
209

210
211
212
213
214
215



















216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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



-
+

-
-
+
+
+
+















-
+


-
-
-
-
-
-
+
+
+
+
+
+




-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+

-
-
-
-
-
+
+
+
+
+

-
+

-
+

-
-
+
+

-
+

-
+
+
+



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * XFree86 vendor specific keysyms.
 *
 * The XFree86 keysym range is 0x10080001 - 0x1008FFFF.
 * 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.
 * The XF86 set of keysyms is a catch-all set of defines for keysyms found
 * on various multimedia keyboards. Originally specific to XFree86 they have
 * been been adopted over time 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 */
#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 */
#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   */
#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     */
#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_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_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_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_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_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_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_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_AudioMicMute          0x1008ffb2  /* Mute the Mic from the system */

#define XF86XK_Keyboard		0x1008FFB3   /* User defined keyboard related action */
#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_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_AudioPreset           0x1008ffb6  /* Select equalizer preset, e.g. theatre-mode */

#define XF86XK_RotationLockToggle 0x1008FFB7 /* Toggle screen rotation lock on/off */
#define XF86XK_RotationLockToggle    0x1008ffb7  /* Toggle screen rotation lock on/off */

#define XF86XK_FullScreen            0x1008ffb8  /* Toggle fullscreen */

/* 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 */
#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 */


/*
 * Reserved range for evdev symbols: 0x10081000-0x10081FFF
 *
 * Key syms within this range must match the Linux kernel
 * input-event-codes.h file in the format:
 *     XF86XK_CamelCaseKernelName	_EVDEVK(kernel value)
 * For example, the kernel
 *   #define KEY_MACRO_RECORD_START	0x2b0
 * effectively ends up as:
 *   #define XF86XK_MacroRecordStart	0x100812b0
 *
 * For historical reasons, some keysyms within the reserved range will be
 * missing, most notably all "normal" keys that are mapped through default
 * XKB layouts (e.g. KEY_Q).
 *
 * CamelCasing is done with a human control as last authority, e.g. see VOD
 * instead of Vod for the Video on Demand key.
 *
 * The format for #defines is strict:
 *
 * #define XF86XK_FOO<tab...>_EVDEVK(0xABC)<tab><tab> |* kver KEY_FOO *|
 *
 * Where
 * - alignment by tabs
 * - the _EVDEVK macro must be used
 * - the hex code must be in uppercase hex
 * - the kernel version (kver) is in the form v5.10
 * - kver and key name are within a slash-star comment (a pipe is used in
 *   this example for technical reasons)
 * These #defines are parsed by scripts. Do not stray from the given format.
 *
 * Where the evdev keycode is mapped to a different symbol, please add a
 * comment line starting with Use: but otherwise the same format, e.g.
 *  Use: XF86XK_RotationLockToggle	_EVDEVK(0x231)		   v4.16 KEY_ROTATE_LOCK_TOGGLE
 *
 */
#define _EVDEVK(_v) (0x10081000 + _v)
/* Use: XF86XK_Eject                    _EVDEVK(0x0a2)             KEY_EJECTCLOSECD */
/* Use: XF86XK_New                      _EVDEVK(0x0b5)     v2.6.14 KEY_NEW */
/* Use: XK_Redo                         _EVDEVK(0x0b6)     v2.6.14 KEY_REDO */
/* KEY_DASHBOARD has been mapped to LaunchB in xkeyboard-config since 2011 */
/* Use: XF86XK_LaunchB                  _EVDEVK(0x0cc)     v2.6.28 KEY_DASHBOARD */
/* Use: XF86XK_Display                  _EVDEVK(0x0e3)     v2.6.12 KEY_SWITCHVIDEOMODE */
/* Use: XF86XK_KbdLightOnOff            _EVDEVK(0x0e4)     v2.6.12 KEY_KBDILLUMTOGGLE */
/* Use: XF86XK_KbdBrightnessDown        _EVDEVK(0x0e5)     v2.6.12 KEY_KBDILLUMDOWN */
/* Use: XF86XK_KbdBrightnessUp          _EVDEVK(0x0e6)     v2.6.12 KEY_KBDILLUMUP */
/* Use: XF86XK_Send                     _EVDEVK(0x0e7)     v2.6.14 KEY_SEND */
/* Use: XF86XK_Reply                    _EVDEVK(0x0e8)     v2.6.14 KEY_REPLY */
/* Use: XF86XK_MailForward              _EVDEVK(0x0e9)     v2.6.14 KEY_FORWARDMAIL */
/* Use: XF86XK_Save                     _EVDEVK(0x0ea)     v2.6.14 KEY_SAVE */
/* Use: XF86XK_Documents                _EVDEVK(0x0eb)     v2.6.14 KEY_DOCUMENTS */
/* Use: XF86XK_Battery                  _EVDEVK(0x0ec)     v2.6.17 KEY_BATTERY */
/* Use: XF86XK_Bluetooth                _EVDEVK(0x0ed)     v2.6.19 KEY_BLUETOOTH */
/* Use: XF86XK_WLAN                     _EVDEVK(0x0ee)     v2.6.19 KEY_WLAN */
/* Use: XF86XK_UWB                      _EVDEVK(0x0ef)     v2.6.24 KEY_UWB */
/* Use: XF86XK_Next_VMode               _EVDEVK(0x0f1)     v2.6.23 KEY_VIDEO_NEXT */
/* Use: XF86XK_Prev_VMode               _EVDEVK(0x0f2)     v2.6.23 KEY_VIDEO_PREV */
/* Use: XF86XK_MonBrightnessCycle       _EVDEVK(0x0f3)     v2.6.23 KEY_BRIGHTNESS_CYCLE */
#define XF86XK_BrightnessAuto           _EVDEVK(0x0f4)  /* v3.16   KEY_BRIGHTNESS_AUTO */
#define XF86XK_DisplayOff               _EVDEVK(0x0f5)  /* v2.6.23 KEY_DISPLAY_OFF */
/* Use: XF86XK_WWAN                     _EVDEVK(0x0f6)     v3.13   KEY_WWAN */
/* Use: XF86XK_RFKill                   _EVDEVK(0x0f7)     v2.6.33 KEY_RFKILL */
/* Use: XF86XK_AudioMicMute             _EVDEVK(0x0f8)     v3.1    KEY_MICMUTE */
#define XF86XK_Info                     _EVDEVK(0x166)  /*         KEY_INFO */
/* Use: XF86XK_CycleAngle               _EVDEVK(0x173)             KEY_ANGLE */
/* Use: XF86XK_FullScreen               _EVDEVK(0x174)     v5.1    KEY_FULL_SCREEN */
#define XF86XK_AspectRatio              _EVDEVK(0x177)  /* v5.1    KEY_ASPECT_RATIO */
#define XF86XK_DVD                      _EVDEVK(0x185)  /*         KEY_DVD */
#define XF86XK_Audio                    _EVDEVK(0x188)  /*         KEY_AUDIO */
/* Use: XF86XK_Video                    _EVDEVK(0x189)             KEY_VIDEO */
/* Use: XF86XK_Calendar                 _EVDEVK(0x18d)             KEY_CALENDAR */
#define XF86XK_ChannelUp                _EVDEVK(0x192)  /*         KEY_CHANNELUP */
#define XF86XK_ChannelDown              _EVDEVK(0x193)  /*         KEY_CHANNELDOWN */
/* Use: XF86XK_AudioRandomPlay          _EVDEVK(0x19a)             KEY_SHUFFLE */
#define XF86XK_Break                    _EVDEVK(0x19b)  /*         KEY_BREAK */
#define XF86XK_VideoPhone               _EVDEVK(0x1a0)  /* v2.6.20 KEY_VIDEOPHONE */
/* Use: XF86XK_Game                     _EVDEVK(0x1a1)     v2.6.20 KEY_GAMES */
/* Use: XF86XK_ZoomIn                   _EVDEVK(0x1a2)     v2.6.20 KEY_ZOOMIN */
/* Use: XF86XK_ZoomOut                  _EVDEVK(0x1a3)     v2.6.20 KEY_ZOOMOUT */
#define XF86XK_ZoomReset                _EVDEVK(0x1a4)  /* v2.6.20 KEY_ZOOMRESET */
/* Use: XF86XK_Word                     _EVDEVK(0x1a5)     v2.6.20 KEY_WORDPROCESSOR */
#define XF86XK_Editor                   _EVDEVK(0x1a6)  /* v2.6.20 KEY_EDITOR */
/* Use: XF86XK_Excel                    _EVDEVK(0x1a7)     v2.6.20 KEY_SPREADSHEET */
#define XF86XK_GraphicsEditor           _EVDEVK(0x1a8)  /* v2.6.20 KEY_GRAPHICSEDITOR */
#define XF86XK_Presentation             _EVDEVK(0x1a9)  /* v2.6.20 KEY_PRESENTATION */
#define XF86XK_Database                 _EVDEVK(0x1aa)  /* v2.6.20 KEY_DATABASE */
/* Use: XF86XK_News                     _EVDEVK(0x1ab)     v2.6.20 KEY_NEWS */
#define XF86XK_Voicemail                _EVDEVK(0x1ac)  /* v2.6.20 KEY_VOICEMAIL */
#define XF86XK_Addressbook              _EVDEVK(0x1ad)  /* v2.6.20 KEY_ADDRESSBOOK */
/* Use: XF86XK_Messenger                _EVDEVK(0x1ae)     v2.6.20 KEY_MESSENGER */
#define XF86XK_DisplayToggle            _EVDEVK(0x1af)  /* v2.6.20 KEY_DISPLAYTOGGLE */
#define XF86XK_SpellCheck               _EVDEVK(0x1b0)  /* v2.6.24 KEY_SPELLCHECK */
/* Use: XF86XK_LogOff                   _EVDEVK(0x1b1)     v2.6.24 KEY_LOGOFF */
/* Use: XK_dollar                       _EVDEVK(0x1b2)     v2.6.24 KEY_DOLLAR */
/* Use: XK_EuroSign                     _EVDEVK(0x1b3)     v2.6.24 KEY_EURO */
/* Use: XF86XK_FrameBack                _EVDEVK(0x1b4)     v2.6.24 KEY_FRAMEBACK */
/* Use: XF86XK_FrameForward             _EVDEVK(0x1b5)     v2.6.24 KEY_FRAMEFORWARD */
#define XF86XK_ContextMenu              _EVDEVK(0x1b6)  /* v2.6.24 KEY_CONTEXT_MENU */
#define XF86XK_MediaRepeat              _EVDEVK(0x1b7)  /* v2.6.26 KEY_MEDIA_REPEAT */
#define XF86XK_10ChannelsUp             _EVDEVK(0x1b8)  /* v2.6.38 KEY_10CHANNELSUP */
#define XF86XK_10ChannelsDown           _EVDEVK(0x1b9)  /* v2.6.38 KEY_10CHANNELSDOWN */
#define XF86XK_Images                   _EVDEVK(0x1ba)  /* v2.6.39 KEY_IMAGES */
#define XF86XK_NotificationCenter       _EVDEVK(0x1bc)  /* v5.10   KEY_NOTIFICATION_CENTER */
#define XF86XK_PickupPhone              _EVDEVK(0x1bd)  /* v5.10   KEY_PICKUP_PHONE */
#define XF86XK_HangupPhone              _EVDEVK(0x1be)  /* v5.10   KEY_HANGUP_PHONE */
#define XF86XK_Fn                       _EVDEVK(0x1d0)  /*         KEY_FN */
#define XF86XK_Fn_Esc                   _EVDEVK(0x1d1)  /*         KEY_FN_ESC */
#define XF86XK_FnRightShift             _EVDEVK(0x1e5)  /* v5.10   KEY_FN_RIGHT_SHIFT */
/* Use: XK_braille_dot_1                _EVDEVK(0x1f1)     v2.6.17 KEY_BRL_DOT1 */
/* Use: XK_braille_dot_2                _EVDEVK(0x1f2)     v2.6.17 KEY_BRL_DOT2 */
/* Use: XK_braille_dot_3                _EVDEVK(0x1f3)     v2.6.17 KEY_BRL_DOT3 */
/* Use: XK_braille_dot_4                _EVDEVK(0x1f4)     v2.6.17 KEY_BRL_DOT4 */
/* Use: XK_braille_dot_5                _EVDEVK(0x1f5)     v2.6.17 KEY_BRL_DOT5 */
/* Use: XK_braille_dot_6                _EVDEVK(0x1f6)     v2.6.17 KEY_BRL_DOT6 */
/* Use: XK_braille_dot_7                _EVDEVK(0x1f7)     v2.6.17 KEY_BRL_DOT7 */
/* Use: XK_braille_dot_8                _EVDEVK(0x1f8)     v2.6.17 KEY_BRL_DOT8 */
/* Use: XK_braille_dot_9                _EVDEVK(0x1f9)     v2.6.23 KEY_BRL_DOT9 */
/* Use: XK_braille_dot_1                _EVDEVK(0x1fa)     v2.6.23 KEY_BRL_DOT10 */
#define XF86XK_Numeric0                 _EVDEVK(0x200)  /* v2.6.28 KEY_NUMERIC_0 */
#define XF86XK_Numeric1                 _EVDEVK(0x201)  /* v2.6.28 KEY_NUMERIC_1 */
#define XF86XK_Numeric2                 _EVDEVK(0x202)  /* v2.6.28 KEY_NUMERIC_2 */
#define XF86XK_Numeric3                 _EVDEVK(0x203)  /* v2.6.28 KEY_NUMERIC_3 */
#define XF86XK_Numeric4                 _EVDEVK(0x204)  /* v2.6.28 KEY_NUMERIC_4 */
#define XF86XK_Numeric5                 _EVDEVK(0x205)  /* v2.6.28 KEY_NUMERIC_5 */
#define XF86XK_Numeric6                 _EVDEVK(0x206)  /* v2.6.28 KEY_NUMERIC_6 */
#define XF86XK_Numeric7                 _EVDEVK(0x207)  /* v2.6.28 KEY_NUMERIC_7 */
#define XF86XK_Numeric8                 _EVDEVK(0x208)  /* v2.6.28 KEY_NUMERIC_8 */
#define XF86XK_Numeric9                 _EVDEVK(0x209)  /* v2.6.28 KEY_NUMERIC_9 */
#define XF86XK_NumericStar              _EVDEVK(0x20a)  /* v2.6.28 KEY_NUMERIC_STAR */
#define XF86XK_NumericPound             _EVDEVK(0x20b)  /* v2.6.28 KEY_NUMERIC_POUND */
#define XF86XK_NumericA                 _EVDEVK(0x20c)  /* v4.1    KEY_NUMERIC_A */
#define XF86XK_NumericB                 _EVDEVK(0x20d)  /* v4.1    KEY_NUMERIC_B */
#define XF86XK_NumericC                 _EVDEVK(0x20e)  /* v4.1    KEY_NUMERIC_C */
#define XF86XK_NumericD                 _EVDEVK(0x20f)  /* v4.1    KEY_NUMERIC_D */
#define XF86XK_CameraFocus              _EVDEVK(0x210)  /* v2.6.33 KEY_CAMERA_FOCUS */
#define XF86XK_WPSButton                _EVDEVK(0x211)  /* v2.6.34 KEY_WPS_BUTTON */
/* Use: XF86XK_TouchpadToggle           _EVDEVK(0x212)     v2.6.37 KEY_TOUCHPAD_TOGGLE */
/* Use: XF86XK_TouchpadOn               _EVDEVK(0x213)     v2.6.37 KEY_TOUCHPAD_ON */
/* Use: XF86XK_TouchpadOff              _EVDEVK(0x214)     v2.6.37 KEY_TOUCHPAD_OFF */
#define XF86XK_CameraZoomIn             _EVDEVK(0x215)  /* v2.6.39 KEY_CAMERA_ZOOMIN */
#define XF86XK_CameraZoomOut            _EVDEVK(0x216)  /* v2.6.39 KEY_CAMERA_ZOOMOUT */
#define XF86XK_CameraUp                 _EVDEVK(0x217)  /* v2.6.39 KEY_CAMERA_UP */
#define XF86XK_CameraDown               _EVDEVK(0x218)  /* v2.6.39 KEY_CAMERA_DOWN */
#define XF86XK_CameraLeft               _EVDEVK(0x219)  /* v2.6.39 KEY_CAMERA_LEFT */
#define XF86XK_CameraRight              _EVDEVK(0x21a)  /* v2.6.39 KEY_CAMERA_RIGHT */
#define XF86XK_AttendantOn              _EVDEVK(0x21b)  /* v3.10   KEY_ATTENDANT_ON */
#define XF86XK_AttendantOff             _EVDEVK(0x21c)  /* v3.10   KEY_ATTENDANT_OFF */
#define XF86XK_AttendantToggle          _EVDEVK(0x21d)  /* v3.10   KEY_ATTENDANT_TOGGLE */
#define XF86XK_LightsToggle             _EVDEVK(0x21e)  /* v3.10   KEY_LIGHTS_TOGGLE */
#define XF86XK_ALSToggle                _EVDEVK(0x230)  /* v3.13   KEY_ALS_TOGGLE */
/* Use: XF86XK_RotationLockToggle       _EVDEVK(0x231)     v4.16   KEY_ROTATE_LOCK_TOGGLE */
#define XF86XK_Buttonconfig             _EVDEVK(0x240)  /* v3.16   KEY_BUTTONCONFIG */
#define XF86XK_Taskmanager              _EVDEVK(0x241)  /* v3.16   KEY_TASKMANAGER */
#define XF86XK_Journal                  _EVDEVK(0x242)  /* v3.16   KEY_JOURNAL */
#define XF86XK_ControlPanel             _EVDEVK(0x243)  /* v3.16   KEY_CONTROLPANEL */
#define XF86XK_AppSelect                _EVDEVK(0x244)  /* v3.16   KEY_APPSELECT */
#define XF86XK_Screensaver              _EVDEVK(0x245)  /* v3.16   KEY_SCREENSAVER */
#define XF86XK_VoiceCommand             _EVDEVK(0x246)  /* v3.16   KEY_VOICECOMMAND */
#define XF86XK_Assistant                _EVDEVK(0x247)  /* v4.13   KEY_ASSISTANT */
/* Use: XK_ISO_Next_Group               _EVDEVK(0x248)     v5.2    KEY_KBD_LAYOUT_NEXT */
#define XF86XK_EmojiPicker              _EVDEVK(0x249)  /* v5.13   KEY_EMOJI_PICKER */
#define XF86XK_Dictate                  _EVDEVK(0x24a)  /* v5.17   KEY_DICTATE */
#define XF86XK_CameraAccessEnable       _EVDEVK(0x24b)  /* v6.2    KEY_CAMERA_ACCESS_ENABLE */
#define XF86XK_CameraAccessDisable      _EVDEVK(0x24c)  /* v6.2    KEY_CAMERA_ACCESS_DISABLE */
#define XF86XK_CameraAccessToggle       _EVDEVK(0x24d)  /* v6.2    KEY_CAMERA_ACCESS_TOGGLE */
#define XF86XK_BrightnessMin            _EVDEVK(0x250)  /* v3.16   KEY_BRIGHTNESS_MIN */
#define XF86XK_BrightnessMax            _EVDEVK(0x251)  /* v3.16   KEY_BRIGHTNESS_MAX */
#define XF86XK_KbdInputAssistPrev       _EVDEVK(0x260)  /* v3.18   KEY_KBDINPUTASSIST_PREV */
#define XF86XK_KbdInputAssistNext       _EVDEVK(0x261)  /* v3.18   KEY_KBDINPUTASSIST_NEXT */
#define XF86XK_KbdInputAssistPrevgroup  _EVDEVK(0x262)  /* v3.18   KEY_KBDINPUTASSIST_PREVGROUP */
#define XF86XK_KbdInputAssistNextgroup  _EVDEVK(0x263)  /* v3.18   KEY_KBDINPUTASSIST_NEXTGROUP */
#define XF86XK_KbdInputAssistAccept     _EVDEVK(0x264)  /* v3.18   KEY_KBDINPUTASSIST_ACCEPT */
#define XF86XK_KbdInputAssistCancel     _EVDEVK(0x265)  /* v3.18   KEY_KBDINPUTASSIST_CANCEL */
#define XF86XK_RightUp                  _EVDEVK(0x266)  /* v4.7    KEY_RIGHT_UP */
#define XF86XK_RightDown                _EVDEVK(0x267)  /* v4.7    KEY_RIGHT_DOWN */
#define XF86XK_LeftUp                   _EVDEVK(0x268)  /* v4.7    KEY_LEFT_UP */
#define XF86XK_LeftDown                 _EVDEVK(0x269)  /* v4.7    KEY_LEFT_DOWN */
#define XF86XK_RootMenu                 _EVDEVK(0x26a)  /* v4.7    KEY_ROOT_MENU */
#define XF86XK_MediaTopMenu             _EVDEVK(0x26b)  /* v4.7    KEY_MEDIA_TOP_MENU */
#define XF86XK_Numeric11                _EVDEVK(0x26c)  /* v4.7    KEY_NUMERIC_11 */
#define XF86XK_Numeric12                _EVDEVK(0x26d)  /* v4.7    KEY_NUMERIC_12 */
#define XF86XK_AudioDesc                _EVDEVK(0x26e)  /* v4.7    KEY_AUDIO_DESC */
#define XF86XK_3DMode                   _EVDEVK(0x26f)  /* v4.7    KEY_3D_MODE */
#define XF86XK_NextFavorite             _EVDEVK(0x270)  /* v4.7    KEY_NEXT_FAVORITE */
#define XF86XK_StopRecord               _EVDEVK(0x271)  /* v4.7    KEY_STOP_RECORD */
#define XF86XK_PauseRecord              _EVDEVK(0x272)  /* v4.7    KEY_PAUSE_RECORD */
#define XF86XK_VOD                      _EVDEVK(0x273)  /* v4.7    KEY_VOD */
#define XF86XK_Unmute                   _EVDEVK(0x274)  /* v4.7    KEY_UNMUTE */
#define XF86XK_FastReverse              _EVDEVK(0x275)  /* v4.7    KEY_FASTREVERSE */
#define XF86XK_SlowReverse              _EVDEVK(0x276)  /* v4.7    KEY_SLOWREVERSE */
#define XF86XK_Data                     _EVDEVK(0x277)  /* v4.7    KEY_DATA */
#define XF86XK_OnScreenKeyboard         _EVDEVK(0x278)  /* v4.12   KEY_ONSCREEN_KEYBOARD */
#define XF86XK_PrivacyScreenToggle      _EVDEVK(0x279)  /* v5.5    KEY_PRIVACY_SCREEN_TOGGLE */
#define XF86XK_SelectiveScreenshot      _EVDEVK(0x27a)  /* v5.6    KEY_SELECTIVE_SCREENSHOT */
#define XF86XK_NextElement              _EVDEVK(0x27b)  /* v5.18   KEY_NEXT_ELEMENT */
#define XF86XK_PreviousElement          _EVDEVK(0x27c)  /* v5.18   KEY_PREVIOUS_ELEMENT */
#define XF86XK_AutopilotEngageToggle    _EVDEVK(0x27d)  /* v5.18   KEY_AUTOPILOT_ENGAGE_TOGGLE */
#define XF86XK_MarkWaypoint             _EVDEVK(0x27e)  /* v5.18   KEY_MARK_WAYPOINT */
#define XF86XK_Sos                      _EVDEVK(0x27f)  /* v5.18   KEY_SOS */
#define XF86XK_NavChart                 _EVDEVK(0x280)  /* v5.18   KEY_NAV_CHART */
#define XF86XK_FishingChart             _EVDEVK(0x281)  /* v5.18   KEY_FISHING_CHART */
#define XF86XK_SingleRangeRadar         _EVDEVK(0x282)  /* v5.18   KEY_SINGLE_RANGE_RADAR */
#define XF86XK_DualRangeRadar           _EVDEVK(0x283)  /* v5.18   KEY_DUAL_RANGE_RADAR */
#define XF86XK_RadarOverlay             _EVDEVK(0x284)  /* v5.18   KEY_RADAR_OVERLAY */
#define XF86XK_TraditionalSonar         _EVDEVK(0x285)  /* v5.18   KEY_TRADITIONAL_SONAR */
#define XF86XK_ClearvuSonar             _EVDEVK(0x286)  /* v5.18   KEY_CLEARVU_SONAR */
#define XF86XK_SidevuSonar              _EVDEVK(0x287)  /* v5.18   KEY_SIDEVU_SONAR */
#define XF86XK_NavInfo                  _EVDEVK(0x288)  /* v5.18   KEY_NAV_INFO */
/* Use: XF86XK_BrightnessAdjust         _EVDEVK(0x289)     v5.18   KEY_BRIGHTNESS_MENU */
#define XF86XK_Macro1                   _EVDEVK(0x290)  /* v5.5    KEY_MACRO1 */
#define XF86XK_Macro2                   _EVDEVK(0x291)  /* v5.5    KEY_MACRO2 */
#define XF86XK_Macro3                   _EVDEVK(0x292)  /* v5.5    KEY_MACRO3 */
#define XF86XK_Macro4                   _EVDEVK(0x293)  /* v5.5    KEY_MACRO4 */
#define XF86XK_Macro5                   _EVDEVK(0x294)  /* v5.5    KEY_MACRO5 */
#define XF86XK_Macro6                   _EVDEVK(0x295)  /* v5.5    KEY_MACRO6 */
#define XF86XK_Macro7                   _EVDEVK(0x296)  /* v5.5    KEY_MACRO7 */
#define XF86XK_Macro8                   _EVDEVK(0x297)  /* v5.5    KEY_MACRO8 */
#define XF86XK_Macro9                   _EVDEVK(0x298)  /* v5.5    KEY_MACRO9 */
#define XF86XK_Macro10                  _EVDEVK(0x299)  /* v5.5    KEY_MACRO10 */
#define XF86XK_Macro11                  _EVDEVK(0x29a)  /* v5.5    KEY_MACRO11 */
#define XF86XK_Macro12                  _EVDEVK(0x29b)  /* v5.5    KEY_MACRO12 */
#define XF86XK_Macro13                  _EVDEVK(0x29c)  /* v5.5    KEY_MACRO13 */
#define XF86XK_Macro14                  _EVDEVK(0x29d)  /* v5.5    KEY_MACRO14 */
#define XF86XK_Macro15                  _EVDEVK(0x29e)  /* v5.5    KEY_MACRO15 */
#define XF86XK_Macro16                  _EVDEVK(0x29f)  /* v5.5    KEY_MACRO16 */
#define XF86XK_Macro17                  _EVDEVK(0x2a0)  /* v5.5    KEY_MACRO17 */
#define XF86XK_Macro18                  _EVDEVK(0x2a1)  /* v5.5    KEY_MACRO18 */
#define XF86XK_Macro19                  _EVDEVK(0x2a2)  /* v5.5    KEY_MACRO19 */
#define XF86XK_Macro20                  _EVDEVK(0x2a3)  /* v5.5    KEY_MACRO20 */
#define XF86XK_Macro21                  _EVDEVK(0x2a4)  /* v5.5    KEY_MACRO21 */
#define XF86XK_Macro22                  _EVDEVK(0x2a5)  /* v5.5    KEY_MACRO22 */
#define XF86XK_Macro23                  _EVDEVK(0x2a6)  /* v5.5    KEY_MACRO23 */
#define XF86XK_Macro24                  _EVDEVK(0x2a7)  /* v5.5    KEY_MACRO24 */
#define XF86XK_Macro25                  _EVDEVK(0x2a8)  /* v5.5    KEY_MACRO25 */
#define XF86XK_Macro26                  _EVDEVK(0x2a9)  /* v5.5    KEY_MACRO26 */
#define XF86XK_Macro27                  _EVDEVK(0x2aa)  /* v5.5    KEY_MACRO27 */
#define XF86XK_Macro28                  _EVDEVK(0x2ab)  /* v5.5    KEY_MACRO28 */
#define XF86XK_Macro29                  _EVDEVK(0x2ac)  /* v5.5    KEY_MACRO29 */
#define XF86XK_Macro30                  _EVDEVK(0x2ad)  /* v5.5    KEY_MACRO30 */
#define XF86XK_MacroRecordStart         _EVDEVK(0x2b0)  /* v5.5    KEY_MACRO_RECORD_START */
#define XF86XK_MacroRecordStop          _EVDEVK(0x2b1)  /* v5.5    KEY_MACRO_RECORD_STOP */
#define XF86XK_MacroPresetCycle         _EVDEVK(0x2b2)  /* v5.5    KEY_MACRO_PRESET_CYCLE */
#define XF86XK_MacroPreset1             _EVDEVK(0x2b3)  /* v5.5    KEY_MACRO_PRESET1 */
#define XF86XK_MacroPreset2             _EVDEVK(0x2b4)  /* v5.5    KEY_MACRO_PRESET2 */
#define XF86XK_MacroPreset3             _EVDEVK(0x2b5)  /* v5.5    KEY_MACRO_PRESET3 */
#define XF86XK_KbdLcdMenu1              _EVDEVK(0x2b8)  /* v5.5    KEY_KBD_LCD_MENU1 */
#define XF86XK_KbdLcdMenu2              _EVDEVK(0x2b9)  /* v5.5    KEY_KBD_LCD_MENU2 */
#define XF86XK_KbdLcdMenu3              _EVDEVK(0x2ba)  /* v5.5    KEY_KBD_LCD_MENU3 */
#define XF86XK_KbdLcdMenu4              _EVDEVK(0x2bb)  /* v5.5    KEY_KBD_LCD_MENU4 */
#define XF86XK_KbdLcdMenu5              _EVDEVK(0x2bc)  /* v5.5    KEY_KBD_LCD_MENU5 */
#undef _EVDEVK
Changes to xlib/X11/Xfuncproto.h.
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
159
160
161
162
163
164
165













166
167
168
169
170
171
172







-
-
-
-
-
-
-
-
-
-
-
-
-







#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
213
214
215
216
217
218
219
220








221
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216








+
+
+
+
+
+
+
+


/* requires xproto >= 7.0.30 */
#if __has_attribute(no_sanitize_thread)
# define _X_NOTSAN __attribute__((no_sanitize_thread))
#else
# define _X_NOTSAN
#endif

/* Mark a char array/pointer as not containing a NUL-terminated string */
/* requires xproto >= 7.0.33 */
#if __has_attribute(nonstring)
# define _X_NONSTRING __attribute__((nonstring))
#else
# define _X_NONSTRING
#endif

#endif /* _XFUNCPROTO_H_ */
Changes to xlib/X11/Xlib.h.
38
39
40
41
42
43
44





45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56



57
58
59






















60
61
62
63
64
65
66







+
+
+
+
+







-
-
-



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







#include <sys/types.h>

#if defined(__SCO__) || defined(__UNIXWARE__)
#include <stdint.h>
#endif

#include <X11/X.h>

#ifdef MAC_OSX_TK
#   define Cursor XCursor
#   define Region XRegion
#endif

/* 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. */
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115








116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137





















138
139
140
141


142
143
144
145
146
147
148
81
82
83
84
85
86
87








88
89
90
91
92
93
94
95
96





















97
98
99
100
101
102
103
104
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 True 1
#define False 0

#define QueuedAlready 0
#define QueuedAfterReading 1
#define QueuedAfterFlush 2

#define ConnectionNumber(dpy) 	((dpy)->fd)
#define RootWindow(dpy, scr) 	(((dpy)->screens[(scr)]).root)
#define DefaultScreen(dpy) 	((dpy)->default_screen)
#define DefaultRootWindow(dpy) 	(((dpy)->screens[(dpy)->default_screen]).root)
#define DefaultVisual(dpy, scr) (((dpy)->screens[(scr)]).root_visual)
#define DefaultGC(dpy, scr) 	(((dpy)->screens[(scr)]).default_gc)
#define BlackPixel(dpy, scr) 	(((dpy)->screens[(scr)]).black_pixel)
#define WhitePixel(dpy, scr) 	(((dpy)->screens[(scr)]).white_pixel)
#define ConnectionNumber(dpy) 	(((_XPrivDisplay)(dpy))->fd)
#define RootWindow(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->root)
#define DefaultScreen(dpy) 	(((_XPrivDisplay)(dpy))->default_screen)
#define DefaultRootWindow(dpy) 	(ScreenOfDisplay(dpy,DefaultScreen(dpy))->root)
#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_visual)
#define DefaultGC(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->default_gc)
#define BlackPixel(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->black_pixel)
#define WhitePixel(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->white_pixel)
#define AllPlanes 		((unsigned long)~0L)
#define QLength(dpy) 		((dpy)->qlen)
#define DisplayWidth(dpy, scr) 	(((dpy)->screens[(scr)]).width)
#define DisplayHeight(dpy, scr) (((dpy)->screens[(scr)]).height)
#define DisplayWidthMM(dpy, scr)(((dpy)->screens[(scr)]).mwidth)
#define DisplayHeightMM(dpy, scr)(((dpy)->screens[(scr)]).mheight)
#define DisplayPlanes(dpy, scr) (((dpy)->screens[(scr)]).root_depth)
#define DisplayCells(dpy, scr) 	(DefaultVisual((dpy), (scr))->map_entries)
#define ScreenCount(dpy) 	((dpy)->nscreens)
#define ServerVendor(dpy) 	((dpy)->vendor)
#define ProtocolVersion(dpy) 	((dpy)->proto_major_version)
#define ProtocolRevision(dpy) 	((dpy)->proto_minor_version)
#define VendorRelease(dpy) 	((dpy)->release)
#define DisplayString(dpy) 	((dpy)->display_name)
#define DefaultDepth(dpy, scr) 	(((dpy)->screens[(scr)]).root_depth)
#define DefaultColormap(dpy, scr)(((dpy)->screens[(scr)]).cmap)
#define BitmapUnit(dpy) 	((dpy)->bitmap_unit)
#define BitmapBitOrder(dpy) 	((dpy)->bitmap_bit_order)
#define BitmapPad(dpy) 		((dpy)->bitmap_pad)
#define ImageByteOrder(dpy) 	((dpy)->byte_order)
#define NextRequest(dpy)	((dpy)->request + 1)
#define LastKnownRequestProcessed(dpy)	((dpy)->request)
#define QLength(dpy) 		(((_XPrivDisplay)(dpy))->qlen)
#define DisplayWidth(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->width)
#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy,scr)->height)
#define DisplayWidthMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mwidth)
#define DisplayHeightMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mheight)
#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth)
#define DisplayCells(dpy, scr) 	(DefaultVisual(dpy,scr)->map_entries)
#define ScreenCount(dpy) 	(((_XPrivDisplay)(dpy))->nscreens)
#define ServerVendor(dpy) 	(((_XPrivDisplay)(dpy))->vendor)
#define ProtocolVersion(dpy) 	(((_XPrivDisplay)(dpy))->proto_major_version)
#define ProtocolRevision(dpy) 	(((_XPrivDisplay)(dpy))->proto_minor_version)
#define VendorRelease(dpy) 	(((_XPrivDisplay)(dpy))->release)
#define DisplayString(dpy) 	(((_XPrivDisplay)(dpy))->display_name)
#define DefaultDepth(dpy, scr) 	(ScreenOfDisplay(dpy,scr)->root_depth)
#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap)
#define BitmapUnit(dpy) 	(((_XPrivDisplay)(dpy))->bitmap_unit)
#define BitmapBitOrder(dpy) 	(((_XPrivDisplay)(dpy))->bitmap_bit_order)
#define BitmapPad(dpy) 		(((_XPrivDisplay)(dpy))->bitmap_pad)
#define ImageByteOrder(dpy) 	(((_XPrivDisplay)(dpy))->byte_order)
#define NextRequest(dpy)	(((_XPrivDisplay)(dpy))->request + 1)
#define LastKnownRequestProcessed(dpy)	(((_XPrivDisplay)(dpy))->request)

/* macros for screen oriented applications (toolkit) */
#define ScreenOfDisplay(dpy, scr)(&((dpy)->screens[(scr)]))
#define DefaultScreenOfDisplay(dpy) (&((dpy)->screens[(dpy)->default_screen]))
#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)(dpy))->screens[scr])
#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy,DefaultScreen(dpy))
#define DisplayOfScreen(s)	((s)->display)
#define RootWindowOfScreen(s)	((s)->root)
#define BlackPixelOfScreen(s)	((s)->black_pixel)
#define WhitePixelOfScreen(s)	((s)->white_pixel)
#define DefaultColormapOfScreen(s)((s)->cmap)
#define DefaultDepthOfScreen(s)	((s)->root_depth)
#define DefaultGCOfScreen(s)	((s)->default_gc)
202
203
204
205
206
207
208
209

210
211
212
213

214
215
216
217
218
219
220
182
183
184
185
186
187
188

189
190
191
192

193
194
195
196
197
198
199
200







-
+



-
+







	unsigned long background;/* background pixel */
	int line_width;		/* line width */
	int line_style;	 	/* LineSolid, LineOnOffDash, LineDoubleDash */
	int cap_style;	  	/* CapNotLast, CapButt,
				   CapRound, CapProjecting */
	int join_style;	 	/* JoinMiter, JoinRound, JoinBevel */
	int fill_style;	 	/* FillSolid, FillTiled,
				   FillStippled, FillOpaeueStippled */
				   FillStippled, FillOpaqueStippled */
	int fill_rule;	  	/* EvenOddRule, WindingRule */
	int arc_mode;		/* ArcChord, ArcPieSlice */
	Pixmap tile;		/* tile pixmap for tiling operations */
	Pixmap stipple;		/* stipple 1 plane pixmap for stipping */
	Pixmap stipple;		/* stipple 1 plane pixmap for stippling */
	int ts_x_origin;	/* offset for tile or stipple operations */
	int ts_y_origin;
        Font font;	        /* default text font for text operations */
	int subwindow_mode;     /* ClipByChildren, IncludeInferiors */
	Bool graphics_exposures;/* boolean, should exposures be generated */
	int clip_x_origin;	/* origin for clipping */
	int clip_y_origin;
300
301
302
303
304
305
306
307

308
309
310
311
312
313
314
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294







-
+







    Pixmap background_pixmap;	/* background or None or ParentRelative */
    unsigned long background_pixel;	/* background pixel */
    Pixmap border_pixmap;	/* border of the window */
    unsigned long border_pixel;	/* border pixel value */
    int bit_gravity;		/* one of bit gravity values */
    int win_gravity;		/* one of the window gravity values */
    int backing_store;		/* NotUseful, WhenMapped, Always */
    unsigned long backing_planes;/* planes to be preseved if possible */
    unsigned long backing_planes;/* planes to be preserved if possible */
    unsigned long backing_pixel;/* value to use in restoring planes */
    Bool save_under;		/* should bits under be saved? (popups) */
    long event_mask;		/* set of events that should be saved */
    long do_not_propagate_mask;	/* set of events that should not propagate */
    Bool override_redirect;	/* boolean value for override-redirect */
    Colormap colormap;		/* color map to be associated with window */
    Cursor cursor;		/* cursor to be displayed (or None) */
372
373
374
375
376
377
378
379

380
381

382
383
384
385
386
387
388
352
353
354
355
356
357
358

359
360

361
362
363
364
365
366
367
368







-
+

-
+







    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 bytes_per_line;		/* accelerator to next line */
    int bits_per_pixel;		/* bits per pixel (ZPixmap) */
    unsigned long red_mask;	/* bits in z arrangment */
    unsigned long red_mask;	/* bits in z arrangement */
    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 */,
488
489
490
491
492
493
494



495



496
497
498
499
500
501
502
468
469
470
471
472
473
474
475
476
477

478
479
480
481
482
483
484
485
486
487







+
+
+
-
+
+
+









/*
 * Display datatype maintaining display specific data.
 * The contents of this structure are implementation dependent.
 * A Display should be treated as opaque by application code.
 */
struct _XPrivate;		/* Forward declare before use for C++ */
struct _XrmHashBucketRec;

typedef struct _XDisplay {
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 */
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
498
499
500
501
502
503
504

505
506
507
508
509
510
511







-







	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;
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
520
521
522
523
524
525
526






























527











528




529
530
531
532
533
534
535
536
537
538
539
540
541
542







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+



+
+







	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 {
	/* there is more to this structure, but it is private to Xlib */
	   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_
Display,
*_XPrivDisplay;

#define XMaxTransChars 7

#undef _XEVENT_
#ifndef _XEVENT_
/*
 * 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 */
1042
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
987
988
989
990
991
992
993

994
995
996
997
998
999
1000
1001







-
+







	XKeymapEvent xkeymap;
	XGenericEvent xgeneric;
	XGenericEventCookie xcookie;
	XID pad[24];
} XEvent;
#endif

#define XAllocID(dpy) ((*(dpy)->resource_alloc)((dpy)))
#define XAllocID(dpy) ((*((_XPrivDisplay)(dpy))->resource_alloc)((dpy)))

/*
 * per character font metric information.
 */
typedef struct {
    short	lbearing;	/* origin to left edge of raster */
    short	rbearing;	/* origin to right edge of raster */
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
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







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-
-
-
-
-





-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








+
+
+
+
+


_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 */
);

typedef void (*XIOErrorExitHandler) ( /* WARNING, this type not in Xlib spec */

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 */
    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 */
);

    void*		/* user_data */
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

#if defined(MAC_OSX_TK)
#   undef Cursor
#   undef Region
#endif

#endif /* _X11_XLIB_H_ */
Changes to xlib/X11/Xutil.h.
57
58
59
60
61
62
63




64
65
66
67
68
69
70
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74







+
+
+
+







   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

#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
#define XValue  	0x0001
#define YValue		0x0002
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211

212
213
214

215
216
217
218

219
220
221
222

223
224
225
226
227
228
229
191
192
193
194
195
196
197














198

199
200

201
202
203

204
205
206
207

208
209
210
211

212
213
214
215
216
217
218
219







-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+

-
+


-
+



-
+



-
+







} 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(
extern int XDestroyImage(
        XImage *ximage);
EXTERN unsigned long XGetPixel(
extern unsigned long XGetPixel(
        XImage *ximage,
        int x, int y);
EXTERN int XPutPixel(
extern int XPutPixel(
        XImage *ximage,
        int x, int y,
        unsigned long pixel);
EXTERN XImage *XSubImage(
extern XImage *XSubImage(
        XImage *ximage,
        int x, int y,
        unsigned int width, unsigned int height);
EXTERN int XAddPixel(
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.
 */
247
248
249
250
251
252
253
254

255
256
257

258
259
260

261
262
263

264
265
266

267
268
269

270
271
272
273
274
275
276
277





278
279
280
281
282



283
284
285
286
287
288
289
237
238
239
240
241
242
243

244
245
246

247
248
249

250
251
252

253
254
255

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 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))
  (((unsigned)(keysym) >= XK_KP_Space) && ((unsigned)(keysym) <= XK_KP_Equal))

#define IsPrivateKeypadKey(keysym) \
  (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))
  (((unsigned)(keysym) >= 0x11000000) && ((unsigned)(keysym) <= 0x1100FFFF))

#define IsCursorKey(keysym) \
  (((KeySym)(keysym) >= XK_Home)     && ((KeySym)(keysym) <  XK_Select))
  (((unsigned)(keysym) >= XK_Home)     && ((unsigned)(keysym) <  XK_Select))

#define IsPFKey(keysym) \
  (((KeySym)(keysym) >= XK_KP_F1)     && ((KeySym)(keysym) <= XK_KP_F4))
  (((unsigned)(keysym) >= XK_KP_F1)     && ((unsigned)(keysym) <= XK_KP_F4))

#define IsFunctionKey(keysym) \
  (((KeySym)(keysym) >= XK_F1)       && ((KeySym)(keysym) <= XK_F35))
  (((unsigned)(keysym) >= XK_F1)       && ((unsigned)(keysym) <= XK_F35))

#define IsMiscFunctionKey(keysym) \
  (((KeySym)(keysym) >= XK_Select)   && ((KeySym)(keysym) <= XK_Break))
  (((unsigned)(keysym) >= XK_Select)   && ((unsigned)(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))
  ((((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R)) \
   || (((unsigned)(keysym) >= XK_ISO_Lock) && \
       ((unsigned)(keysym) <= XK_ISO_Level5_Lock)) \
   || ((unsigned)(keysym) == XK_Mode_switch) \
   || ((unsigned)(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))
  ((((unsigned)(keysym) >= XK_Shift_L) && ((unsigned)(keysym) <= XK_Hyper_R)) \
   || ((unsigned)(keysym) == XK_Mode_switch) \
   || ((unsigned)(keysym) == XK_Num_Lock))
#endif
/*
 * 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
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385

386
387
388
389









390
391
392
393
394

395
396
397
398

399
400

401
402
403
404
405
406

407
408
409
410

411
412
413
414

415
416
417
418
419

420
421
422
423
424
425
426

427
428
429
430
431
432

433
434
435
436
437
438
439

440
441
442
443
444
445

446
447
448
449
450
451
452
453

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







-
+
+
+
+
+
+
+
+
+



-
+



-
+



-
-
-
-
-
-
-
-
-
+




-
+



-
+

-
+





-
+



-
+



-
+




-
+






-
+





-
+






-
+





-
+







-
+






-
+






-
+






-
+

-
-
-
+
+
+
+
+
+
+


-
+





-
-
-
-
-
-
+





-
-
-
-
-
-
-
+






-
+







-
+





-
+





-
+





-
+







-
+







-
+





-
+





-
+





-
+







-
+






-
+





-
+






-
+





-
+







-
+






-
+










-
+






+
+
+
+
+
+
-
+





-
-
-
-
-
-
-
+





-
-
-
-
-
-
-
+





-
+











-
+











-
+











-
+






-
+





-
+






-
+





-
+





-
-
-
-
-
-
-
+





-
+







-
+







-
+







-
+



-
+





-
+






-
+






-
+






-
+





-
+





-
+













-
+











+
+
+
+

#define XUniqueContext()       ((XContext) XrmUniqueQuark())
#define XStringToContext(string)   ((XContext) XrmStringToQuark(string))

_XFUNCPROTOBEGIN

/* The following declarations are alphabetized. */

EXTERN XClassHint *XAllocClassHint (
extern XClassHint *XAllocClassHint (
    void
);

extern XIconSize *XAllocIconSize (
    void
);

extern XSizeHints *XAllocSizeHints (
    void
);

EXTERN XIconSize *XAllocIconSize (
extern XStandardColormap *XAllocStandardColormap (
    void
);

EXTERN XSizeHints *XAllocSizeHints (
extern XWMHints *XAllocWMHints (
    void
);

EXTERN XStandardColormap *XAllocStandardColormap (
    void
);

EXTERN XWMHints *XAllocWMHints (
    void
);

EXTERN int XClipBox(
extern int XClipBox(
    Region		/* r */,
    XRectangle*		/* rect_return */
);

EXTERN Region XCreateRegion(
extern Region XCreateRegion(
    void
);

EXTERN const char *XDefaultString (void);
extern const char *XDefaultString (void);

EXTERN int XDeleteContext(
extern int XDeleteContext(
    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */
);

EXTERN int XDestroyRegion(
extern int XDestroyRegion(
    Region		/* r */
);

EXTERN int XEmptyRegion(
extern Bool XEmptyRegion(
    Region		/* r */
);

EXTERN int XEqualRegion(
extern Bool XEqualRegion(
    Region		/* r1 */,
    Region		/* r2 */
);

EXTERN int XFindContext(
extern int XFindContext(
    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */,
    XPointer*		/* data_return */
);

EXTERN Status XGetClassHint(
extern Status XGetClassHint(
    Display*		/* display */,
    Window		/* w */,
    XClassHint*		/* class_hints_return */
);

EXTERN Status XGetIconSizes(
extern Status XGetIconSizes(
    Display*		/* display */,
    Window		/* w */,
    XIconSize**		/* size_list_return */,
    int*		/* count_return */
);

EXTERN Status XGetNormalHints(
extern Status XGetNormalHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */
);

EXTERN Status XGetRGBColormaps(
extern Status XGetRGBColormaps(
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap** /* stdcmap_return */,
    int*		/* count_return */,
    Atom		/* property */
);

EXTERN Status XGetSizeHints(
extern Status XGetSizeHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    Atom		/* property */
);

EXTERN Status XGetStandardColormap(
extern Status XGetStandardColormap(
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* colormap_return */,
    Atom		/* property */
);

EXTERN Status XGetTextProperty(
extern Status XGetTextProperty(
    Display*		/* display */,
    Window		/* window */,
    XTextProperty*	/* text_prop_return */,
    Atom		/* property */
);

EXTERN XVisualInfo *XGetVisualInfo(
extern Status XGetWMClientMachine(
    Display*		/* display */,
    long		/* vinfo_mask */,
    XVisualInfo*	/* vinfo_template */,
    int*		/* nitems_return */
    Window		/* w */,
    XTextProperty*	/* text_prop_return */
);

extern XWMHints *XGetWMHints(
    Display*		/* display */,
    Window		/* w */
);

EXTERN Status XGetWMClientMachine(
extern Status XGetWMIconName(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */
);

EXTERN XWMHints *XGetWMHints(
    Display*		/* display */,
    Window		/* w */
);

EXTERN Status XGetWMIconName(
extern Status XGetWMName(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */
);

EXTERN Status XGetWMName(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop_return */
);

EXTERN Status XGetWMNormalHints(
extern Status XGetWMNormalHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    long*		/* supplied_return */
);

EXTERN Status XGetWMSizeHints(
extern Status XGetWMSizeHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints_return */,
    long*		/* supplied_return */,
    Atom		/* property */
);

EXTERN Status XGetZoomHints(
extern Status XGetZoomHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* zhints_return */
);

EXTERN int XIntersectRegion(
extern int XIntersectRegion(
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
);

EXTERN void XConvertCase(
extern void XConvertCase(
    KeySym		/* sym */,
    KeySym*		/* lower */,
    KeySym*		/* upper */
);

EXTERN int XLookupString(
extern int XLookupString(
    XKeyEvent*		/* event_struct */,
    char*		/* buffer_return */,
    int			/* bytes_buffer */,
    KeySym*		/* keysym_return */,
    XComposeStatus*	/* status_in_out */
);

EXTERN Status XMatchVisualInfo(
extern Status XMatchVisualInfo(
    Display*		/* display */,
    int			/* screen */,
    int			/* depth */,
    int			/* class */,
    XVisualInfo*	/* vinfo_return */
);

EXTERN int XOffsetRegion(
extern int XOffsetRegion(
    Region		/* r */,
    int			/* dx */,
    int			/* dy */
);

EXTERN Bool XPointInRegion(
extern Bool XPointInRegion(
    Region		/* r */,
    int			/* x */,
    int			/* y */
);

EXTERN Region XPolygonRegion(
extern Region XPolygonRegion(
    XPoint*		/* points */,
    int			/* n */,
    int			/* fill_rule */
);

EXTERN int XRectInRegion(
extern int XRectInRegion(
    Region		/* r */,
    int			/* x */,
    int			/* y */,
    unsigned int	/* width */,
    unsigned int	/* height */
);

EXTERN int XSaveContext(
extern int XSaveContext(
    Display*		/* display */,
    XID			/* rid */,
    XContext		/* context */,
    _Xconst char*	/* data */
);

EXTERN int XSetClassHint(
extern int XSetClassHint(
    Display*		/* display */,
    Window		/* w */,
    XClassHint*		/* class_hints */
);

EXTERN int XSetIconSizes(
extern int XSetIconSizes(
    Display*		/* display */,
    Window		/* w */,
    XIconSize*		/* size_list */,
    int			/* count */
);

EXTERN int XSetNormalHints(
extern int XSetNormalHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */
);

EXTERN void XSetRGBColormaps(
extern void XSetRGBColormaps(
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* stdcmaps */,
    int			/* count */,
    Atom		/* property */
);

EXTERN int XSetSizeHints(
extern int XSetSizeHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */,
    Atom		/* property */
);

EXTERN int XSetStandardProperties(
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(
extern void XSetTextProperty(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */,
    Atom		/* property */
);

extern int XSetWMHints(
    Display*		/* display */,
    Window		/* w */,
    XWMHints*		/* wm_hints */
);

EXTERN void XSetWMClientMachine(
extern void XSetWMIconName(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */
);

EXTERN int XSetWMHints(
    Display*		/* display */,
    Window		/* w */,
    XWMHints*		/* wm_hints */
);

EXTERN void XSetWMIconName(
extern void XSetWMName(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */
);

EXTERN void XSetWMName(
    Display*		/* display */,
    Window		/* w */,
    XTextProperty*	/* text_prop */
);

EXTERN void XSetWMNormalHints(
extern void XSetWMNormalHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */
);

EXTERN void XSetWMProperties(
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(
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(
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(
extern void XSetWMSizeHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* hints */,
    Atom		/* property */
);

EXTERN int XSetRegion(
extern int XSetRegion(
    Display*		/* display */,
    GC			/* gc */,
    Region		/* r */
);

EXTERN void XSetStandardColormap(
extern void XSetStandardColormap(
    Display*		/* display */,
    Window		/* w */,
    XStandardColormap*	/* colormap */,
    Atom		/* property */
);

EXTERN int XSetZoomHints(
extern int XSetZoomHints(
    Display*		/* display */,
    Window		/* w */,
    XSizeHints*		/* zhints */
);

EXTERN int XShrinkRegion(
extern int XShrinkRegion(
    Region		/* r */,
    int			/* dx */,
    int			/* dy */
);

EXTERN Status XStringListToTextProperty(
    char**		/* list */,
    int			/* count */,
    XTextProperty*	/* text_prop_return */
);

EXTERN int XSubtractRegion(
extern int XSubtractRegion(
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
);

EXTERN int XmbTextListToTextProperty(
extern int XmbTextListToTextProperty(
    Display*		display,
    char**		list,
    int			count,
    XICCEncodingStyle	style,
    XTextProperty*	text_prop_return
);

EXTERN int XwcTextListToTextProperty(
extern int XwcTextListToTextProperty(
    Display*		display,
    wchar_t**		list,
    int			count,
    XICCEncodingStyle	style,
    XTextProperty*	text_prop_return
);

EXTERN int Xutf8TextListToTextProperty(
extern int Xutf8TextListToTextProperty(
    Display*		display,
    char**		list,
    int			count,
    XICCEncodingStyle	style,
    XTextProperty*	text_prop_return
);

EXTERN void XwcFreeStringList(
extern void XwcFreeStringList(
    wchar_t**		list
);

EXTERN Status XTextPropertyToStringList(
extern Status XTextPropertyToStringList(
    XTextProperty*	/* text_prop */,
    char***		/* list_return */,
    int*		/* count_return */
);

EXTERN int XmbTextPropertyToTextList(
extern int XmbTextPropertyToTextList(
    Display*		display,
    const XTextProperty* text_prop,
    char***		list_return,
    int*		count_return
);

EXTERN int XwcTextPropertyToTextList(
extern int XwcTextPropertyToTextList(
    Display*		display,
    const XTextProperty* text_prop,
    wchar_t***		list_return,
    int*		count_return
);

EXTERN int Xutf8TextPropertyToTextList(
extern int Xutf8TextPropertyToTextList(
    Display*		display,
    const XTextProperty* text_prop,
    char***		list_return,
    int*		count_return
);

EXTERN int XUnionRectWithRegion(
extern int XUnionRectWithRegion(
    XRectangle*		/* rectangle */,
    Region		/* src_region */,
    Region		/* dest_region_return */
);

EXTERN int XUnionRegion(
extern int XUnionRegion(
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
);

EXTERN int XWMGeometry(
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(
extern int XXorRegion(
    Region		/* sra */,
    Region		/* srb */,
    Region		/* dr_return */
);

#ifdef __clang__
#pragma clang diagnostic pop
#endif

_XFUNCPROTOEND

#if defined(MAC_OSX_TK)
#   undef Region
#endif

#endif /* _X11_XUTIL_H_ */
Changes to xlib/X11/ap_keysym.h.
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23







-
+







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
TO THIS SOFTWARE, 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
Changes to xlib/X11/keysymdef.h.
57
58
59
60
61
62
63









64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84




85










































86
87
88
89
90



91
92
93
94
95
96
97
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142


143
144
145
146
147
148
149
150
151
152







+
+
+
+
+
+
+
+
+




















-
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
-
+
+
+







 * 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.
 *
 * Some keysyms map to a character already mapped by another keysym,
 * with compatible but more precise semantics, such as the keypad-
 * related keysyms. In this case, none of the keysym are deprecated.
 * The most generic keysym is annotated as previously and more specific
 * keysyms have the same annotation between angle brackets:
 *
 *     #define XK_space                 0x0020  // U+0020 SPACE
 *     #define XK_KP_Space              0xff80  //<U+0020 SPACE>
 *
 * 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.
 * file, the first one listed is considered the "canonical" name. This
 * is the name that should be used when retrieving a keysym name from
 * its code. The next names are considered "aliases" to the canonical
 * name.
 *
 * Aliases are made explicit by writing in their comment "alias for",
 * followed by the corresponding canonical name. Example:
 *
 *     #define XK_dead_tilde            0xfe53
 *     #define XK_dead_perispomeni      0xfe53 // alias for dead_tilde
 *
 * The rules to consider a keysym mnemonic name deprecated are:
 *
 *   1. A legacy keysym with its Unicode mapping in parentheses is
 *      deprecated (see above).
 *
 *   2. A keysym name is *explicitly* deprecated by starting its comment
 *      with "deprecated". Examples:
 *
 *        #define XK_L1           0xffc8  // deprecated alias for F11
 *        #define XK_quoteleft    0x0060  // deprecated
 *
 *   3. A keysym name is *explicitly* *not* deprecated by starting its
 *      comment with "non-deprecated alias". Examples:
 *
 *       #define XK_dead_tilde       0xfe53
 *       #define XK_dead_perispomeni 0xfe53 // non-deprecated alias for dead_tilde
 *
 *   4. If none of the previous rules apply, an alias is *implicitly*
 *      deprecated if there is at least one previous name for the
 *      corresponding keysym that is *not* explicitly deprecated.
 *
 *      Examples:
 *
 *        // SingleCandidate is the canonical name
 *        #define XK_SingleCandidate        0xff3c
 *        // Hangul_SingleCandidate is deprecated because it is an alias
 *        // and it does not start with "non-deprecated alias"
 *        #define XK_Hangul_SingleCandidate 0xff3c // Single candidate
 *
 *        // guillemotleft is the canonical name, but it is deprecated
 *        #define XK_guillemotleft  0x00ab // deprecated alias for guillemetleft (misspelling)
 *        // guillemetleft is not deprecated, because the keysym has no endorsed name before it.
 *        #define XK_guillemetleft  0x00ab // U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
 *        // The following hypothetical name is deprecated because guillemetleft come before.
 *        #define XK_guillemetleft2 0x00ab
 *
 * 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*\/\* 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*\/\*\(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,
106
107
108
109
110
111
112





















113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128





129
130
131
132
133


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199





200
201
202
203
204
205
206
207


208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-
-
-
-
-
+
+
+
+
+



-
-
+
+
















-
+







 *
 *   - 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
 *
 * Before removing or changing the order of the keysyms, please consider
 * the following: it is very difficult to know what keysyms are used and
 * how.
 *
 *   - A sandboxed application may have incompatibilities with the host
 *     system. For example, if new keysym name is introduced and is made
 *     the canonical name, then an application with an older keysym parser
 *     will not be able to parse the new name.
 *   - Customization of keyboard layout and Compose files are two popular
 *     use cases. Checking the standard keyboard layout database xkeyboard-config
 *     https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config
 *     and the standard Compose files in libx11
 *     https://gitlab.freedesktop.org/xorg/lib/libx11 is a mandatory
 *     step, but may *not* be enough for a proper impact assessment for
 *     e.g. keysyms removals.
 *
 * Therefore, it is advised to proceed to no removal and to make a new
 * name canonical only 10 years after its introduction. This means that
 * some keysyms may have their first listed name deprecated during the
 * period of transition. Once this period is over, the deprecated name
 * should be moved after the new canonical name.
 */

#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_BackSpace                     0xff08  /* U+0008 BACKSPACE */
#define XK_Tab                           0xff09  /* U+0009 CHARACTER TABULATION */
#define XK_Linefeed                      0xff0a  /* U+000A LINE FEED */
#define XK_Clear                         0xff0b  /* U+000B LINE TABULATION */
#define XK_Return                        0xff0d  /* U+000D CARRIAGE RETURN */
#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 */
#define XK_Escape                        0xff1b  /* U+001B ESCAPE */
#define XK_Delete                        0xffff  /* U+007F DELETE */



/* 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_Henkan                        0xff23  /* non-deprecated 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 */
171
172
173
174
175
176
177
178

179
180

181
182
183
184
185
186
187
247
248
249
250
251
252
253

254
255

256
257
258
259
260
261
262
263







-
+

-
+








#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_Page_Up                       0xff55  /* deprecated alias for Prior */
#define XK_Next                          0xff56  /* Next */
#define XK_Page_Down                     0xff56
#define XK_Page_Down                     0xff56  /* deprecated alias for Next */
#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 */
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211



212
213
214
215
216
217
218
219
220
221
222

223
224

225
226
227
228
229
230
231
232
233
234
235







236
237
238
239
240
241
242
243
244
245
246










247
248
249
250
251
252
253
273
274
275
276
277
278
279

280
281
282
283
284



285
286
287
288
289
290
291
292
293
294
295
296
297

298
299

300
301
302
303
304







305
306
307
308
309
310
311
312










313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329







-
+




-
-
-
+
+
+










-
+

-
+




-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+







#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_script_switch                 0xff7e  /* non-deprecated 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_Space                      0xff80  /*<U+0020 SPACE>*/
#define XK_KP_Tab                        0xff89  /*<U+0009 CHARACTER TABULATION>*/
#define XK_KP_Enter                      0xff8d  /*<U+000D CARRIAGE RETURN>*/
#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_Page_Up                    0xff9a  /* deprecated alias for KP_Prior */
#define XK_KP_Next                       0xff9b
#define XK_KP_Page_Down                  0xff9b
#define XK_KP_Page_Down                  0xff9b  /* deprecated alias for KP_Next */
#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_Equal                      0xffbd  /*<U+003D EQUALS SIGN>*/
#define XK_KP_Multiply                   0xffaa  /*<U+002A ASTERISK>*/
#define XK_KP_Add                        0xffab  /*<U+002B PLUS SIGN>*/
#define XK_KP_Separator                  0xffac  /*<U+002C COMMA>*/
#define XK_KP_Subtract                   0xffad  /*<U+002D HYPHEN-MINUS>*/
#define XK_KP_Decimal                    0xffae  /*<U+002E FULL STOP>*/
#define XK_KP_Divide                     0xffaf  /*<U+002F SOLIDUS>*/

#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
#define XK_KP_0                          0xffb0  /*<U+0030 DIGIT ZERO>*/
#define XK_KP_1                          0xffb1  /*<U+0031 DIGIT ONE>*/
#define XK_KP_2                          0xffb2  /*<U+0032 DIGIT TWO>*/
#define XK_KP_3                          0xffb3  /*<U+0033 DIGIT THREE>*/
#define XK_KP_4                          0xffb4  /*<U+0034 DIGIT FOUR>*/
#define XK_KP_5                          0xffb5  /*<U+0035 DIGIT FIVE>*/
#define XK_KP_6                          0xffb6  /*<U+0036 DIGIT SIX>*/
#define XK_KP_7                          0xffb7  /*<U+0037 DIGIT SEVEN>*/
#define XK_KP_8                          0xffb8  /*<U+0038 DIGIT EIGHT>*/
#define XK_KP_9                          0xffb9  /*<U+0039 DIGIT NINE>*/



/*
 * 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.
261
262
263
264
265
266
267
268

269
270

271
272

273
274

275
276

277
278

279
280

281
282

283
284

285
286

287
288

289
290

291
292

293
294

295
296

297
298

299
300

301
302

303
304

305
306

307
308

309
310

311
312

313
314

315
316

317
318
319
320
321
322
323
337
338
339
340
341
342
343

344
345

346
347

348
349

350
351

352
353

354
355

356
357

358
359

360
361

362
363

364
365

366
367

368
369

370
371

372
373

374
375

376
377

378
379

380
381

382
383

384
385

386
387

388
389

390
391

392
393
394
395
396
397
398
399







-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+

-
+







#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_L1                            0xffc8  /* deprecated alias for F11 */
#define XK_F12                           0xffc9
#define XK_L2                            0xffc9
#define XK_L2                            0xffc9  /* deprecated alias for F12 */
#define XK_F13                           0xffca
#define XK_L3                            0xffca
#define XK_L3                            0xffca  /* deprecated alias for F13 */
#define XK_F14                           0xffcb
#define XK_L4                            0xffcb
#define XK_L4                            0xffcb  /* deprecated alias for F14 */
#define XK_F15                           0xffcc
#define XK_L5                            0xffcc
#define XK_L5                            0xffcc  /* deprecated alias for F15 */
#define XK_F16                           0xffcd
#define XK_L6                            0xffcd
#define XK_L6                            0xffcd  /* deprecated alias for F16 */
#define XK_F17                           0xffce
#define XK_L7                            0xffce
#define XK_L7                            0xffce  /* deprecated alias for F17 */
#define XK_F18                           0xffcf
#define XK_L8                            0xffcf
#define XK_L8                            0xffcf  /* deprecated alias for F18 */
#define XK_F19                           0xffd0
#define XK_L9                            0xffd0
#define XK_L9                            0xffd0  /* deprecated alias for F19 */
#define XK_F20                           0xffd1
#define XK_L10                           0xffd1
#define XK_L10                           0xffd1  /* deprecated alias for F20 */
#define XK_F21                           0xffd2
#define XK_R1                            0xffd2
#define XK_R1                            0xffd2  /* deprecated alias for F21 */
#define XK_F22                           0xffd3
#define XK_R2                            0xffd3
#define XK_R2                            0xffd3  /* deprecated alias for F22 */
#define XK_F23                           0xffd4
#define XK_R3                            0xffd4
#define XK_R3                            0xffd4  /* deprecated alias for F23 */
#define XK_F24                           0xffd5
#define XK_R4                            0xffd5
#define XK_R4                            0xffd5  /* deprecated alias for F24 */
#define XK_F25                           0xffd6
#define XK_R5                            0xffd6
#define XK_R5                            0xffd6  /* deprecated alias for F25 */
#define XK_F26                           0xffd7
#define XK_R6                            0xffd7
#define XK_R6                            0xffd7  /* deprecated alias for F26 */
#define XK_F27                           0xffd8
#define XK_R7                            0xffd8
#define XK_R7                            0xffd8  /* deprecated alias for F27 */
#define XK_F28                           0xffd9
#define XK_R8                            0xffd9
#define XK_R8                            0xffd9  /* deprecated alias for F28 */
#define XK_F29                           0xffda
#define XK_R9                            0xffda
#define XK_R9                            0xffda  /* deprecated alias for F29 */
#define XK_F30                           0xffdb
#define XK_R10                           0xffdb
#define XK_R10                           0xffdb  /* deprecated alias for F30 */
#define XK_F31                           0xffdc
#define XK_R11                           0xffdc
#define XK_R11                           0xffdc  /* deprecated alias for F31 */
#define XK_F32                           0xffdd
#define XK_R12                           0xffdd
#define XK_R12                           0xffdd  /* deprecated alias for F32 */
#define XK_F33                           0xffde
#define XK_R13                           0xffde
#define XK_R13                           0xffde  /* deprecated alias for F33 */
#define XK_F34                           0xffdf
#define XK_R14                           0xffdf
#define XK_R14                           0xffdf  /* deprecated alias for F34 */
#define XK_F35                           0xffe0
#define XK_R15                           0xffe0
#define XK_R15                           0xffe0  /* deprecated alias for F35 */

/* 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 */
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435







-
+







#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_Shift               0xff7e  /* non-deprecated 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
383
384
385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408

409
410

411
412
413
414
415
416
417
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







-
+

















-
+

-
+







#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_perispomeni              0xfe53  /* non-deprecated 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_psili                    0xfe64  /* non-deprecated alias for dead_abovecomma */
#define XK_dead_abovereversedcomma       0xfe65
#define XK_dead_dasia                    0xfe65  /* alias for dead_abovereversedcomma */
#define XK_dead_dasia                    0xfe65  /* non-deprecated 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
432
433
434
435
436
437
438
439
440




441
442

443
444
445
446
447
448
449
508
509
510
511
512
513
514


515
516
517
518
519
520
521
522
523
524
525
526
527
528







-
-
+
+
+
+


+







#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_small_schwa              0xfe8a  /* deprecated alias for dead_schwa */
#define XK_dead_schwa                    0xfe8a
#define XK_dead_capital_schwa            0xfe8b  /* deprecated alias for dead_SCHWA */
#define XK_dead_SCHWA                    0xfe8b

#define XK_dead_greek                    0xfe8c
#define XK_dead_hamza                    0xfe8d

#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

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
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







+
-
+














-
-
+
+
+
+







#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  /* deprecated alias for guillemetleft (misspelling) */
#define XK_guillemotleft                 0x00ab  /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
#define XK_guillemetleft                 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_masculine                     0x00ba  /* deprecated alias for ordmasculine (inconsistent name) */
#define XK_ordmasculine                  0x00ba  /* U+00BA MASCULINE ORDINAL INDICATOR */
#define XK_guillemotright                0x00bb  /* deprecated alias for guillemetright (misspelling) */
#define XK_guillemetright                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 */
698
699
700
701
702
703
704
705

706
707
708
709
710
711
712
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794







-
+







#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_Ooblique                      0x00d8  /* deprecated alias for Oslash */
#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 */
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746
814
815
816
817
818
819
820

821
822
823
824
825
826
827
828







-
+







#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_ooblique                      0x00f8  /* deprecated alias for oslash */
#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 */
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
1096







-
+







#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 */
#define XK_kana_switch                   0xff7e  /* non-deprecated alias for Mode_switch */
#endif /* XK_KATAKANA */

/*
 * Arabic
 * Byte 3 = 5
 */

1096
1097
1098
1099
1100
1101
1102
1103

1104
1105
1106

1107
1108
1109
1110
1111
1112
1113
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187

1188
1189
1190
1191
1192
1193
1194
1195







-
+


-
+







#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_farsi_yeh           0x10006cc  /* deprecated alias for 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 */
#define XK_Arabic_switch                 0xff7e  /* non-deprecated alias for Mode_switch */
#endif /* XK_ARABIC */

/*
 * Cyrillic
 * Byte 3 = 6
 */
#ifdef XK_CYRILLIC
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1344
1345
1346
1347
1348
1349
1350

1351
1352
1353
1354
1355
1356
1357
1358







-
+








#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_IOTAdiaeresis           0x07a5  /* deprecated (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 */
1291
1292
1293
1294
1295
1296
1297
1298

1299
1300
1301
1302
1303
1304
1305
1373
1374
1375
1376
1377
1378
1379

1380
1381
1382
1383
1384
1385
1386
1387







-
+







#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_LAMBDA                  0x07cb  /* non-deprecated alias for Greek_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 */
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
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







-
+














-
+







#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_lambda                  0x07eb  /* non-deprecated alias for Greek_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 */
#define XK_Greek_switch                  0xff7e  /* non-deprecated 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
 */
1456
1457
1458
1459
1460
1461
1462
1463

1464
1465

1466
1467
1468
1469
1470
1471
1472
1538
1539
1540
1541
1542
1543
1544

1545
1546

1547
1548
1549
1550
1551
1552
1553
1554







-
+

-
+







#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_leftanglebracket              0x0abc  /*(U+2329 LEFT-POINTING ANGLE BRACKET)*/
#define XK_decimalpoint                  0x0abd  /*(U+002E FULL STOP)*/
#define XK_rightanglebracket             0x0abe  /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/
#define XK_rightanglebracket             0x0abe  /*(U+232A RIGHT-POINTING 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)*/
1591
1592
1593
1594
1595
1596
1597
1598

1599
1600
1601
1602
1603
1604
1605
1673
1674
1675
1676
1677
1678
1679

1680
1681
1682
1683
1684
1685
1686
1687







-
+







#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 */
#define XK_Hebrew_switch                 0xff7e  /* non-deprecated alias for Mode_switch */
#endif /* XK_HEBREW */

/*
 * Thai
 * Byte 3 = 0x0d
 */

1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1740
1741
1742
1743
1744
1745
1746

1747
1748
1749
1750
1751
1752
1753
1754







-
+







#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_maihanakat_maitho        0x0dde  /*(U+0E3E Unassigned code point)*/
#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 */
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
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







-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
-
+
+


-
-
-
+
+
+













-
+

-
+

-
+

-
+

-
+

-
+







#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 */
#define XK_Hangul_switch                 0xff7e  /* non-deprecated 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
#define XK_Hangul_Kiyeog                 0x0ea1  /* U+3131 HANGUL LETTER KIYEOK */
#define XK_Hangul_SsangKiyeog            0x0ea2  /* U+3132 HANGUL LETTER SSANGKIYEOK */
#define XK_Hangul_KiyeogSios             0x0ea3  /* U+3133 HANGUL LETTER KIYEOK-SIOS */
#define XK_Hangul_Nieun                  0x0ea4  /* U+3134 HANGUL LETTER NIEUN */
#define XK_Hangul_NieunJieuj             0x0ea5  /* U+3135 HANGUL LETTER NIEUN-CIEUC */
#define XK_Hangul_NieunHieuh             0x0ea6  /* U+3136 HANGUL LETTER NIEUN-HIEUH */
#define XK_Hangul_Dikeud                 0x0ea7  /* U+3137 HANGUL LETTER TIKEUT */
#define XK_Hangul_SsangDikeud            0x0ea8  /* U+3138 HANGUL LETTER SSANGTIKEUT */
#define XK_Hangul_Rieul                  0x0ea9  /* U+3139 HANGUL LETTER RIEUL */
#define XK_Hangul_RieulKiyeog            0x0eaa  /* U+313A HANGUL LETTER RIEUL-KIYEOK */
#define XK_Hangul_RieulMieum             0x0eab  /* U+313B HANGUL LETTER RIEUL-MIEUM */
#define XK_Hangul_RieulPieub             0x0eac  /* U+313C HANGUL LETTER RIEUL-PIEUP */
#define XK_Hangul_RieulSios              0x0ead  /* U+313D HANGUL LETTER RIEUL-SIOS */
#define XK_Hangul_RieulTieut             0x0eae  /* U+313E HANGUL LETTER RIEUL-THIEUTH */
#define XK_Hangul_RieulPhieuf            0x0eaf  /* U+313F HANGUL LETTER RIEUL-PHIEUPH */
#define XK_Hangul_RieulHieuh             0x0eb0  /* U+3140 HANGUL LETTER RIEUL-HIEUH */
#define XK_Hangul_Mieum                  0x0eb1  /* U+3141 HANGUL LETTER MIEUM */
#define XK_Hangul_Pieub                  0x0eb2  /* U+3142 HANGUL LETTER PIEUP */
#define XK_Hangul_SsangPieub             0x0eb3  /* U+3143 HANGUL LETTER SSANGPIEUP */
#define XK_Hangul_PieubSios              0x0eb4  /* U+3144 HANGUL LETTER PIEUP-SIOS */
#define XK_Hangul_Sios                   0x0eb5  /* U+3145 HANGUL LETTER SIOS */
#define XK_Hangul_SsangSios              0x0eb6  /* U+3146 HANGUL LETTER SSANGSIOS */
#define XK_Hangul_Ieung                  0x0eb7  /* U+3147 HANGUL LETTER IEUNG */
#define XK_Hangul_Jieuj                  0x0eb8  /* U+3148 HANGUL LETTER CIEUC */
#define XK_Hangul_SsangJieuj             0x0eb9  /* U+3149 HANGUL LETTER SSANGCIEUC */
#define XK_Hangul_Cieuc                  0x0eba  /* U+314A HANGUL LETTER CHIEUCH */
#define XK_Hangul_Khieuq                 0x0ebb  /* U+314B HANGUL LETTER KHIEUKH */
#define XK_Hangul_Tieut                  0x0ebc  /* U+314C HANGUL LETTER THIEUTH */
#define XK_Hangul_Phieuf                 0x0ebd  /* U+314D HANGUL LETTER PHIEUPH */
#define XK_Hangul_Hieuh                  0x0ebe  /* U+314E HANGUL LETTER HIEUH */

/* 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
#define XK_Hangul_A                      0x0ebf  /* U+314F HANGUL LETTER A */
#define XK_Hangul_AE                     0x0ec0  /* U+3150 HANGUL LETTER AE */
#define XK_Hangul_YA                     0x0ec1  /* U+3151 HANGUL LETTER YA */
#define XK_Hangul_YAE                    0x0ec2  /* U+3152 HANGUL LETTER YAE */
#define XK_Hangul_EO                     0x0ec3  /* U+3153 HANGUL LETTER EO */
#define XK_Hangul_E                      0x0ec4  /* U+3154 HANGUL LETTER E */
#define XK_Hangul_YEO                    0x0ec5  /* U+3155 HANGUL LETTER YEO */
#define XK_Hangul_YE                     0x0ec6  /* U+3156 HANGUL LETTER YE */
#define XK_Hangul_O                      0x0ec7  /* U+3157 HANGUL LETTER O */
#define XK_Hangul_WA                     0x0ec8  /* U+3158 HANGUL LETTER WA */
#define XK_Hangul_WAE                    0x0ec9  /* U+3159 HANGUL LETTER WAE */
#define XK_Hangul_OE                     0x0eca  /* U+315A HANGUL LETTER OE */
#define XK_Hangul_YO                     0x0ecb  /* U+315B HANGUL LETTER YO */
#define XK_Hangul_U                      0x0ecc  /* U+315C HANGUL LETTER U */
#define XK_Hangul_WEO                    0x0ecd  /* U+315D HANGUL LETTER WEO */
#define XK_Hangul_WE                     0x0ece  /* U+315E HANGUL LETTER WE */
#define XK_Hangul_WI                     0x0ecf  /* U+315F HANGUL LETTER WI */
#define XK_Hangul_YU                     0x0ed0  /* U+3160 HANGUL LETTER YU */
#define XK_Hangul_EU                     0x0ed1  /* U+3161 HANGUL LETTER EU */
#define XK_Hangul_YI                     0x0ed2  /* U+3162 HANGUL LETTER YI */
#define XK_Hangul_I                      0x0ed3  /* U+3163 HANGUL LETTER I */

/* 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
#define XK_Hangul_J_Kiyeog               0x0ed4  /* U+11A8 HANGUL JONGSEONG KIYEOK */
#define XK_Hangul_J_SsangKiyeog          0x0ed5  /* U+11A9 HANGUL JONGSEONG SSANGKIYEOK */
#define XK_Hangul_J_KiyeogSios           0x0ed6  /* U+11AA HANGUL JONGSEONG KIYEOK-SIOS */
#define XK_Hangul_J_Nieun                0x0ed7  /* U+11AB HANGUL JONGSEONG NIEUN */
#define XK_Hangul_J_NieunJieuj           0x0ed8  /* U+11AC HANGUL JONGSEONG NIEUN-CIEUC */
#define XK_Hangul_J_NieunHieuh           0x0ed9  /* U+11AD HANGUL JONGSEONG NIEUN-HIEUH */
#define XK_Hangul_J_Dikeud               0x0eda  /* U+11AE HANGUL JONGSEONG TIKEUT */
#define XK_Hangul_J_Rieul                0x0edb  /* U+11AF HANGUL JONGSEONG RIEUL */
#define XK_Hangul_J_RieulKiyeog          0x0edc  /* U+11B0 HANGUL JONGSEONG RIEUL-KIYEOK */
#define XK_Hangul_J_RieulMieum           0x0edd  /* U+11B1 HANGUL JONGSEONG RIEUL-MIEUM */
#define XK_Hangul_J_RieulPieub           0x0ede  /* U+11B2 HANGUL JONGSEONG RIEUL-PIEUP */
#define XK_Hangul_J_RieulSios            0x0edf  /* U+11B3 HANGUL JONGSEONG RIEUL-SIOS */
#define XK_Hangul_J_RieulTieut           0x0ee0  /* U+11B4 HANGUL JONGSEONG RIEUL-THIEUTH */
#define XK_Hangul_J_RieulPhieuf          0x0ee1  /* U+11B5 HANGUL JONGSEONG RIEUL-PHIEUPH */
#define XK_Hangul_J_RieulHieuh           0x0ee2  /* U+11B6 HANGUL JONGSEONG RIEUL-HIEUH */
#define XK_Hangul_J_Mieum                0x0ee3  /* U+11B7 HANGUL JONGSEONG MIEUM */
#define XK_Hangul_J_Pieub                0x0ee4  /* U+11B8 HANGUL JONGSEONG PIEUP */
#define XK_Hangul_J_PieubSios            0x0ee5  /* U+11B9 HANGUL JONGSEONG PIEUP-SIOS */
#define XK_Hangul_J_Sios                 0x0ee6  /* U+11BA HANGUL JONGSEONG SIOS */
#define XK_Hangul_J_SsangSios            0x0ee7  /* U+11BB HANGUL JONGSEONG SSANGSIOS */
#define XK_Hangul_J_Ieung                0x0ee8  /* U+11BC HANGUL JONGSEONG IEUNG */
#define XK_Hangul_J_Jieuj                0x0ee9  /* U+11BD HANGUL JONGSEONG CIEUC */
#define XK_Hangul_J_Cieuc                0x0eea  /* U+11BE HANGUL JONGSEONG CHIEUCH */
#define XK_Hangul_J_Khieuq               0x0eeb  /* U+11BF HANGUL JONGSEONG KHIEUKH */
#define XK_Hangul_J_Tieut                0x0eec  /* U+11C0 HANGUL JONGSEONG THIEUTH */
#define XK_Hangul_J_Phieuf               0x0eed  /* U+11C1 HANGUL JONGSEONG PHIEUPH */
#define XK_Hangul_J_Hieuh                0x0eee  /* U+11C2 HANGUL JONGSEONG HIEUH */

/* 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
#define XK_Hangul_RieulYeorinHieuh       0x0eef  /* U+316D HANGUL LETTER RIEUL-YEORINHIEUH */
#define XK_Hangul_SunkyeongeumMieum      0x0ef0  /* U+3171 HANGUL LETTER KAPYEOUNMIEUM */
#define XK_Hangul_SunkyeongeumPieub      0x0ef1  /* U+3178 HANGUL LETTER KAPYEOUNPIEUP */
#define XK_Hangul_PanSios                0x0ef2  /* U+317F HANGUL LETTER PANSIOS */
#define XK_Hangul_KkogjiDalrinIeung      0x0ef3  /* U+3181 HANGUL LETTER YESIEUNG */
#define XK_Hangul_SunkyeongeumPhieuf     0x0ef4  /* U+3184 HANGUL LETTER KAPYEOUNPHIEUPH */
#define XK_Hangul_YeorinHieuh            0x0ef5  /* U+3186 HANGUL LETTER YEORINHIEUH */

/* Ancient Hangul Vowel Characters */
#define XK_Hangul_AraeA                  0x0ef6
#define XK_Hangul_AraeAE                 0x0ef7
#define XK_Hangul_AraeA                  0x0ef6  /* U+318D HANGUL LETTER ARAEA */
#define XK_Hangul_AraeAE                 0x0ef7  /* U+318E HANGUL LETTER ARAEAE */

/* Ancient Hangul syllable-final (JongSeong) Characters */
#define XK_Hangul_J_PanSios              0x0ef8
#define XK_Hangul_J_KkogjiDalrinIeung    0x0ef9
#define XK_Hangul_J_YeorinHieuh          0x0efa
#define XK_Hangul_J_PanSios              0x0ef8  /* U+11EB HANGUL JONGSEONG PANSIOS */
#define XK_Hangul_J_KkogjiDalrinIeung    0x0ef9  /* U+11F0 HANGUL JONGSEONG YESIEUNG */
#define XK_Hangul_J_YeorinHieuh          0x0efa  /* U+11F9 HANGUL JONGSEONG YEORINHIEUH */

/* 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_verjaket          0x1000589  /* deprecated alias for 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_but               0x100055d  /* deprecated alias for Armenian_separation_mark */
#define XK_Armenian_hyphen            0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_yentamna          0x100058a  /* U+058A ARMENIAN HYPHEN */
#define XK_Armenian_yentamna          0x100058a  /* deprecated alias for 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_amanak            0x100055c  /* deprecated alias for Armenian_exclam */
#define XK_Armenian_accent            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_shesht            0x100055b  /* U+055B ARMENIAN EMPHASIS MARK */
#define XK_Armenian_shesht            0x100055b  /* deprecated alias for Armenian_accent */
#define XK_Armenian_question          0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_paruyk            0x100055e  /* U+055E ARMENIAN QUESTION MARK */
#define XK_Armenian_paruyk            0x100055e  /* deprecated alias for Armenian_question */
#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 */
2085
2086
2087
2088
2089
2090
2091





2092
2093
2094
2095
2096
2097
2098
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185







+
+
+
+
+







#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 */
#define XK_combining_tilde            0x1000303  /* U+0303 COMBINING TILDE */
#define XK_combining_grave            0x1000300  /* U+0300 COMBINING GRAVE ACCENT */
#define XK_combining_acute            0x1000301  /* U+0301 COMBINING ACUTE ACCENT */
#define XK_combining_hook             0x1000309  /* U+0309 COMBINING HOOK ABOVE */
#define XK_combining_belowdot         0x1000323  /* U+0323 COMBINING DOT BELOW */

#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 */
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
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







-
+


-
-
-
-
-
-
+
+
+
+
+
+

-
-
+
+







#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_emptyset                   0x1002205  /* U+2205 EMPTY 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_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_approxeq                   0x1002248  /*(U+2248 ALMOST EQUAL TO)*/
#define XK_notapproxeq                0x1002247  /*(U+2247 NEITHER APPROXIMATELY NOR ACTUALLY 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
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
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







-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
+
+
+
+
+
+










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






-







-

#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_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_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_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_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_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_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_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_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_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 */
#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 */
#define XK_Sinh_ng                    0x1000d82  /* U+0D82 SINHALA SIGN ANUSVARAYA */
#define XK_Sinh_h2                    0x1000d83  /* U+0D83 SINHALA SIGN VISARGAYA */
#define XK_Sinh_a                     0x1000d85  /* U+0D85 SINHALA LETTER AYANNA */
#define XK_Sinh_aa                    0x1000d86  /* U+0D86 SINHALA LETTER AAYANNA */
#define XK_Sinh_ae                    0x1000d87  /* U+0D87 SINHALA LETTER AEYANNA */
#define XK_Sinh_aee                   0x1000d88  /* U+0D88 SINHALA LETTER AEEYANNA */
#define XK_Sinh_i                     0x1000d89  /* U+0D89 SINHALA LETTER IYANNA */
#define XK_Sinh_ii                    0x1000d8a  /* U+0D8A SINHALA LETTER IIYANNA */
#define XK_Sinh_u                     0x1000d8b  /* U+0D8B SINHALA LETTER UYANNA */
#define XK_Sinh_uu                    0x1000d8c  /* U+0D8C SINHALA LETTER UUYANNA */
#define XK_Sinh_ri                    0x1000d8d  /* U+0D8D SINHALA LETTER IRUYANNA */
#define XK_Sinh_rii                   0x1000d8e  /* U+0D8E SINHALA LETTER IRUUYANNA */
#define XK_Sinh_lu                    0x1000d8f  /* U+0D8F SINHALA LETTER ILUYANNA */
#define XK_Sinh_luu                   0x1000d90  /* U+0D90 SINHALA LETTER ILUUYANNA */
#define XK_Sinh_e                     0x1000d91  /* U+0D91 SINHALA LETTER EYANNA */
#define XK_Sinh_ee                    0x1000d92  /* U+0D92 SINHALA LETTER EEYANNA */
#define XK_Sinh_ai                    0x1000d93  /* U+0D93 SINHALA LETTER AIYANNA */
#define XK_Sinh_o                     0x1000d94  /* U+0D94 SINHALA LETTER OYANNA */
#define XK_Sinh_oo                    0x1000d95  /* U+0D95 SINHALA LETTER OOYANNA */
#define XK_Sinh_au                    0x1000d96  /* U+0D96 SINHALA LETTER AUYANNA */
#define XK_Sinh_ka                    0x1000d9a  /* U+0D9A SINHALA LETTER ALPAPRAANA KAYANNA */
#define XK_Sinh_kha                   0x1000d9b  /* U+0D9B SINHALA LETTER MAHAAPRAANA KAYANNA */
#define XK_Sinh_ga                    0x1000d9c  /* U+0D9C SINHALA LETTER ALPAPRAANA GAYANNA */
#define XK_Sinh_gha                   0x1000d9d  /* U+0D9D SINHALA LETTER MAHAAPRAANA GAYANNA */
#define XK_Sinh_ng2                   0x1000d9e  /* U+0D9E SINHALA LETTER KANTAJA NAASIKYAYA */
#define XK_Sinh_nga                   0x1000d9f  /* U+0D9F SINHALA LETTER SANYAKA GAYANNA */
#define XK_Sinh_ca                    0x1000da0  /* U+0DA0 SINHALA LETTER ALPAPRAANA CAYANNA */
#define XK_Sinh_cha                   0x1000da1  /* U+0DA1 SINHALA LETTER MAHAAPRAANA CAYANNA */
#define XK_Sinh_ja                    0x1000da2  /* U+0DA2 SINHALA LETTER ALPAPRAANA JAYANNA */
#define XK_Sinh_jha                   0x1000da3  /* U+0DA3 SINHALA LETTER MAHAAPRAANA JAYANNA */
#define XK_Sinh_nya                   0x1000da4  /* U+0DA4 SINHALA LETTER TAALUJA NAASIKYAYA */
#define XK_Sinh_jnya                  0x1000da5  /* U+0DA5 SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA */
#define XK_Sinh_nja                   0x1000da6  /* U+0DA6 SINHALA LETTER SANYAKA JAYANNA */
#define XK_Sinh_tta                   0x1000da7  /* U+0DA7 SINHALA LETTER ALPAPRAANA TTAYANNA */
#define XK_Sinh_ttha                  0x1000da8  /* U+0DA8 SINHALA LETTER MAHAAPRAANA TTAYANNA */
#define XK_Sinh_dda                   0x1000da9  /* U+0DA9 SINHALA LETTER ALPAPRAANA DDAYANNA */
#define XK_Sinh_ddha                  0x1000daa  /* U+0DAA SINHALA LETTER MAHAAPRAANA DDAYANNA */
#define XK_Sinh_nna                   0x1000dab  /* U+0DAB SINHALA LETTER MUURDHAJA NAYANNA */
#define XK_Sinh_ndda                  0x1000dac  /* U+0DAC SINHALA LETTER SANYAKA DDAYANNA */
#define XK_Sinh_tha                   0x1000dad  /* U+0DAD SINHALA LETTER ALPAPRAANA TAYANNA */
#define XK_Sinh_thha                  0x1000dae  /* U+0DAE SINHALA LETTER MAHAAPRAANA TAYANNA */
#define XK_Sinh_dha                   0x1000daf  /* U+0DAF SINHALA LETTER ALPAPRAANA DAYANNA */
#define XK_Sinh_dhha                  0x1000db0  /* U+0DB0 SINHALA LETTER MAHAAPRAANA DAYANNA */
#define XK_Sinh_na                    0x1000db1  /* U+0DB1 SINHALA LETTER DANTAJA NAYANNA */
#define XK_Sinh_ndha                  0x1000db3  /* U+0DB3 SINHALA LETTER SANYAKA DAYANNA */
#define XK_Sinh_pa                    0x1000db4  /* U+0DB4 SINHALA LETTER ALPAPRAANA PAYANNA */
#define XK_Sinh_pha                   0x1000db5  /* U+0DB5 SINHALA LETTER MAHAAPRAANA PAYANNA */
#define XK_Sinh_ba                    0x1000db6  /* U+0DB6 SINHALA LETTER ALPAPRAANA BAYANNA */
#define XK_Sinh_bha                   0x1000db7  /* U+0DB7 SINHALA LETTER MAHAAPRAANA BAYANNA */
#define XK_Sinh_ma                    0x1000db8  /* U+0DB8 SINHALA LETTER MAYANNA */
#define XK_Sinh_mba                   0x1000db9  /* U+0DB9 SINHALA LETTER AMBA BAYANNA */
#define XK_Sinh_ya                    0x1000dba  /* U+0DBA SINHALA LETTER YAYANNA */
#define XK_Sinh_ra                    0x1000dbb  /* U+0DBB SINHALA LETTER RAYANNA */
#define XK_Sinh_la                    0x1000dbd  /* U+0DBD SINHALA LETTER DANTAJA LAYANNA */
#define XK_Sinh_va                    0x1000dc0  /* U+0DC0 SINHALA LETTER VAYANNA */
#define XK_Sinh_sha                   0x1000dc1  /* U+0DC1 SINHALA LETTER TAALUJA SAYANNA */
#define XK_Sinh_ssha                  0x1000dc2  /* U+0DC2 SINHALA LETTER MUURDHAJA SAYANNA */
#define XK_Sinh_sa                    0x1000dc3  /* U+0DC3 SINHALA LETTER DANTAJA SAYANNA */
#define XK_Sinh_ha                    0x1000dc4  /* U+0DC4 SINHALA LETTER HAYANNA */
#define XK_Sinh_lla                   0x1000dc5  /* U+0DC5 SINHALA LETTER MUURDHAJA LAYANNA */
#define XK_Sinh_fa                    0x1000dc6  /* U+0DC6 SINHALA LETTER FAYANNA */
#define XK_Sinh_al                    0x1000dca  /* U+0DCA SINHALA SIGN AL-LAKUNA */
#define XK_Sinh_aa2                   0x1000dcf  /* U+0DCF SINHALA VOWEL SIGN AELA-PILLA */
#define XK_Sinh_ae2                   0x1000dd0  /* U+0DD0 SINHALA VOWEL SIGN KETTI AEDA-PILLA */
#define XK_Sinh_aee2                  0x1000dd1  /* U+0DD1 SINHALA VOWEL SIGN DIGA AEDA-PILLA */
#define XK_Sinh_i2                    0x1000dd2  /* U+0DD2 SINHALA VOWEL SIGN KETTI IS-PILLA */
#define XK_Sinh_ii2                   0x1000dd3  /* U+0DD3 SINHALA VOWEL SIGN DIGA IS-PILLA */
#define XK_Sinh_u2                    0x1000dd4  /* U+0DD4 SINHALA VOWEL SIGN KETTI PAA-PILLA */
#define XK_Sinh_uu2                   0x1000dd6  /* U+0DD6 SINHALA VOWEL SIGN DIGA PAA-PILLA */
#define XK_Sinh_ru2                   0x1000dd8  /* U+0DD8 SINHALA VOWEL SIGN GAETTA-PILLA */
#define XK_Sinh_e2                    0x1000dd9  /* U+0DD9 SINHALA VOWEL SIGN KOMBUVA */
#define XK_Sinh_ee2                   0x1000dda  /* U+0DDA SINHALA VOWEL SIGN DIGA KOMBUVA */
#define XK_Sinh_ai2                   0x1000ddb  /* U+0DDB SINHALA VOWEL SIGN KOMBU DEKA */
#define XK_Sinh_o2                    0x1000ddc  /* U+0DDC SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA */
#define XK_Sinh_oo2                   0x1000ddd  /* U+0DDD SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA */
#define XK_Sinh_au2                   0x1000dde  /* U+0DDE SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA */
#define XK_Sinh_lu2                   0x1000ddf  /* U+0DDF SINHALA VOWEL SIGN GAYANUKITTA */
#define XK_Sinh_ruu2                  0x1000df2  /* U+0DF2 SINHALA VOWEL SIGN DIGA GAETTA-PILLA */
#define XK_Sinh_luu2                  0x1000df3  /* U+0DF3 SINHALA VOWEL SIGN DIGA GAYANUKITTA */
#define XK_Sinh_kunddaliya            0x1000df4  /* U+0DF4 SINHALA PUNCTUATION 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 */

Changes to xlib/xcolors.c.
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15






-
-
+
+







/*
 * xcolors.c --
 *
 *	This file contains the routines used to map from X color names to RGB
 *	and pixel values.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright (c) 2012 by Jan Nijtmans
 * Copyright (c) 1996 Sun Microsystems, Inc.
 * Copyright (c) 2012 Jan Nijtmans
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

40
41
42
43
44
45
46
47

48
49

50
51
52
53

54
55
56


57
58

59
60
61
62
63
64
65
66

67
68

69
70
71
72


73
74
75
76
77
78





79
80
81
82
83


84
85

86
87
88
89



90
91
92
93


94
95
96

97
98
99
100
101



102
103
104


105
106
107
108
109

110
111

112
113
114

115
116
117
118
119
120

121
122
123

124
125
126
127

128
129

130
131
132

133
134
135
136
137
138




139
140
141

142
143
144
145



146
147
148
149
150



151
152
153
154
155


156
157
158
159
160
161
162
163
164







165
166

167
168
169
170


171
172
173


174
175
176
177
178
179

180
181
182
183

184
185

186
187
188

189
190
191

192
193
194
195
196
197

198
199

200
201
202
203

204
205
206
207

208
209
210
211
212
213

214
215
216
217
218

219
220

221
222
223
224
225


226
227

228
229
230
231
232
233
234
40
41
42
43
44
45
46

47
48

49
50
51
52

53
54


55
56
57

58
59
60
61
62
63
64
65

66
67

68
69
70


71
72
73





74
75
76
77
78
79
80
81


82
83
84

85
86



87
88
89
90
91


92
93
94
95

96
97
98



99
100
101
102


103
104
105
106
107
108

109
110

111
112
113

114
115
116
117
118
119

120
121
122

123
124
125
126

127
128

129
130
131

132
133
134




135
136
137
138
139
140

141
142



143
144
145
146
147



148
149
150
151
152
153


154
155
156
157







158
159
160
161
162
163
164
165

166
167
168


169
170
171


172
173
174
175
176
177
178

179
180
181
182

183
184

185
186
187

188
189
190

191
192
193
194
195
196

197
198

199
200
201
202

203
204
205
206

207
208
209
210
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",
    "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\0",
    "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\0",
    "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\0",
    "lanchedAlmond\0              \377\353\315\0",
    "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\0",
    "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\0",
    "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\0",
    "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\0",
    "arkCyan\0                    \000\213\213\0",
    "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\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",
    "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\0",
    "arkSalmon\0                  \351\226\172\0",
    "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\0",
    "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\0",
    "arkTurquoise\0               \000\316\321\0",
    "arkViolet\0                  \224\000\323\0",
    "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\0",
    "imGrey\0                     \151\151\151\0",
    "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                              \0" /* placeholder */,
    "\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\0",
    "orestGreen\0                 \042\213\042\0",
    "uchsia\0                     \377\000\377\0",
    "loralWhite\0                 \377\372\360",
    "orestGreen\0                 \042\213\042",
    "uchsia\0                     \377\000\377",
    /* Colors starting with 'g' */
    "ainsboro\0                   \334\334\334\0",
    "hostWhite\0                  \370\370\377\0",
    "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\200\200\200\10",
    "ray0\0                       \000\000\000\0",
    "ray0\0                       \000\000\000",
    "reen\0           \000\213\000\000\315\000\000\356\000\000\377\000\000\200\000\4",
    "reenYellow\0                 \255\377\057\0",
    "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\200\200\200\10",
    "rey0\0                       \000\000\000\0",
    "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\0",
    "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                              \0" /* placeholder */,
    "\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\0",
    "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\0",
    "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\0",
    "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\0",
    "ightGray\0                   \323\323\323\0",
    "ightGreen\0                  \220\356\220\0",
    "ightGrey\0                   \323\323\323\0",
    "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\0",
    "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\0",
    "ightSlateGray\0              \167\210\231\0",
    "ightSlateGrey\0              \167\210\231\0",
    "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\0",
    "imeGreen\0                   \062\315\062\0",
    "inen\0                       \372\360\346\0",
    "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\200\000\000\4",
    "ediumAquamarine\0            \146\315\252\0",
    "ediumBlue\0                  \000\000\315\0",
    "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\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",
    "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\0",
    "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\0",
    "avyBlue\0                    \000\000\200\0",
    "avy\0                        \000\000\200",
    "avyBlue\0                    \000\000\200",
    /* Colors starting with 'o' */
    "ldLace\0                     \375\365\346\0",
    "live\0                       \200\200\000\0",
    "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\0",
    "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\0",
    "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\0",
    "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\0",
    "owderBlue\0                  \260\340\346",
    "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 */,
    "\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\0",
    "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\0",
    "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\0",
    "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\0",
    "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\0",
    "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                              \0" /* placeholder */,
    "\377" /* placeholder */,
    /* Colors starting with 'v' */
    "iolet\0                      \356\202\356\0",
    "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\0",
    "hiteSmoke\0                  \365\365\365\0",
    "hite\0                       \377\377\377",
    "hiteSmoke\0                  \365\365\365",
    /* Colors starting with 'x' */
    "\377                              \0" /* placeholder */,
    "\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"
};

/*
 *----------------------------------------------------------------------
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316







-
+







	    notequal = 1;
	}
	c = *spec++;
	if ((unsigned)(c - 'A') <= (unsigned)('Z' - 'A')) {
	    c += 'a' - 'A';
	} else if (((unsigned)(c - '1') <= (unsigned)('9' - '1'))) {
	    if (d == '0') {
	    	d += 10;
		d += 10;
	    } else if (!d) {
		num = c - '0';
		while ((unsigned)((c = *spec++) - '0') <= (unsigned)('9' - '0')) {
		    num = num * 10 + c - '0';
		}
	    }
	}
332
333
334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349
350
351
352
353
332
333
334
335
336
337
338


339
340
341
342
343



344
345
346
347
348
349
350







-
-
+
+



-
-
-







#define RED(p)		((unsigned char) (p)[0])
#define GREEN(p)	((unsigned char) (p)[1])
#define BLUE(p)		((unsigned char) (p)[2])
#define US(expr)	((unsigned short) (expr))

Status
XParseColor(
    Display *display,
    Colormap map,
    TCL_UNUSED(Display *),
    TCL_UNUSED(Colormap),
    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.
413
414
415
416
417
418
419
420

421
422
423
424

425
426
427
428
429
430
431
410
411
412
413
414
415
416

417
418
419
420

421
422
423
424
425
426
427
428







-
+



-
+







	    if (!size) {
		return 0;
	    }
	    r = colorcmp(spec + 1, *p, &num);
	}
	if (num > (*p)[31]) {
	    if (((*p)[31] != 8) || num > 100) {
	    	return 0;
		return 0;
	    }
	    num = (num * 255 + 50) / 100;
	    if ((num == 230) || (num == 128)) {
	    	/*
		/*
		 * Those two entries have a deviation i.r.t the table.
		 */

		num--;
	    }
	    num |= (num << 8);
	    colorPtr->red = colorPtr->green = colorPtr->blue = num;
Changes to xlib/xgc.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
9
10
11
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 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)
#include <X11/Xlib.h>
#if defined(MAC_OSX_TK)
#   define Cursor XCursor
#   define Region XRegion
#else
#   include <tkMacOSXInt.h>
#   include <X11/Xlib.h>
#   include <X11/X.h>
#endif

#undef TkSetRegion

#define MAX_DASH_LIST_SIZE 10
typedef struct {
    XGCValues gc;
    char dash[MAX_DASH_LIST_SIZE];
#ifdef MAC_OSX_TK
    TkpGCCache cache;
#endif
} XGCValuesWithCache;
} XGCValuesWithDash;

/*
 *----------------------------------------------------------------------
 *
 * AllocClipMask --
 *
 *	Static helper proc to allocate new or clear existing TkpClipMask.
53
54
55
56
57
58
59


60


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83






84


85
86
87
88
89
90
91
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92







+
+

+
+




















-
-
-
+
+
+
+
+
+

+
+








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;
    } else if (clip_mask->type == TKP_CLIP_REGION) {
	TkDestroyRegion(clip_mask->value.region);
    }
    clip_mask->type = TKP_CLIP_PIXMAP;
    clip_mask->value.pixmap = None;
    return clip_mask;
}

/*
 *----------------------------------------------------------------------
 *
 * FreeClipMask --
 *
 *	Static helper proc to free TkpClipMask.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void FreeClipMask(GC gc) {
    if (gc->clip_mask != None) {
	ckfree((char *)gc->clip_mask);
	gc->clip_mask = None;
    TkpClipMask * clip_mask = (TkpClipMask*)gc->clip_mask;
    if (clip_mask == NULL) {
	return;
    }
    if (clip_mask->type == TKP_CLIP_REGION) {
	TkDestroyRegion(clip_mask->value.region);
    }
    ckfree(clip_mask);
    gc->clip_mask = None;
}

/*
 *----------------------------------------------------------------------
 *
 * XCreateGC --
 *
113
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
114
115
116
117
118
119
120

121



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144







-
+
-
-
-















-
+







    /*
     * 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));
    gp = (GC)ckalloc(sizeof(XGCValuesWithDash));
    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(fill_rule,	  GCFillRule,		EvenOddRule);
    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);
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
152
153
154
155
156
157
158


159
160
161





















162
163
164
165
166
167
168







-
-



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    gp->clip_mask = None;
    if (mask & GCClipMask) {
	TkpClipMask *clip_mask = AllocClipMask(gp);

	clip_mask->type = TKP_CLIP_PIXMAP;
	clip_mask->value.pixmap = values->clip_mask;
    }
    TkpInitGCCache(gp);

    return gp;
}

#ifdef MAC_OSX_TK
/*
 *----------------------------------------------------------------------
 *
 * TkpGetGCCache --
 *
 * Results:
 *	Pointer to the TkpGCCache at the end of the GC.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkpGCCache*
TkpGetGCCache(GC gc) {
    return (gc ? &((XGCValuesWithCache *)gc)->cache : NULL);
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * XChangeGC --
 *
 *	Changes the GC components specified by valuemask for the specified GC.
 *
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
236
237
238
239
240
241
242

243
244
245
246
247
248
249







-







    Display *d,
    GC gc)
{
    (void)d;

    if (gc != NULL) {
	FreeClipMask(gc);
	TkpFreeGCCache(gc);
	ckfree(gc);
    }
    return Success;
}

/*
 *----------------------------------------------------------------------
454
455
456
457
458
459
460
461

462
463
464
465
466


467
468
469
470
471
472
473
474
475
428
429
430
431
432
433
434

435
436
437
438


439
440


441
442
443
444
445
446
447







-
+



-
-
+
+
-
-







    gc->clip_y_origin = clip_y_origin;
    return Success;
}

/*
 *----------------------------------------------------------------------
 *
 * TkSetRegion, XSetClipMask --
 * TkSetRegion, XSetClipMask, XSetClipRectangles --
 *
 *	Sets the clipping region/pixmap for a GC.
 *
 *	Note that unlike the Xlib equivalent, it is not safe to delete the
 *	region after setting it into the GC (except on Mac OS X). The only
 *	Like the Xlib equivalent, it is safe to delete the
 *	region after setting it into the GC.
 *	uses of TkSetRegion are currently in DisplayFrame and in
 *	ImgPhotoDisplay, which use the GC immediately.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Allocates or deallocates a TkpClipMask.
 *
487
488
489
490
491
492
493


494
495
496
497
498
499
500
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474







+
+







    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;
	clip_mask->value.region = TkCreateRegion();
	TkpCopyRegion(clip_mask->value.region, r);
    }
    return Success;
}

int
XSetClipMask(
    Display *display,
509
510
511
512
513
514
515


























516
517
518
519
520
521
522
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	TkpClipMask *clip_mask = AllocClipMask(gc);

	clip_mask->type = TKP_CLIP_PIXMAP;
	clip_mask->value.pixmap = pixmap;
    }
    return Success;
}

int
XSetClipRectangles(
    TCL_UNUSED(Display*),
    GC gc,
    int clip_x_origin,
    int clip_y_origin,
    XRectangle* rectangles,
    int n,
    TCL_UNUSED(int))
{
    TkRegion clipRgn = TkCreateRegion();
    TkpClipMask * clip_mask = AllocClipMask(gc);
    clip_mask->type = TKP_CLIP_REGION;
    clip_mask->value.region = clipRgn;

    while (n--) {
	XRectangle rect = *rectangles;

	rect.x += clip_x_origin;
	rect.y += clip_y_origin;
	TkUnionRectWithRegion(&rect, clipRgn, clipRgn);
	rectangles++;
    }
    return 1;
}

/*
 * Some additional dummy functions (hopefully implemented soon).
 */

#if 0
Cursor
587
588
589
590
591
592
593

594
595
596
597
598
599
600
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601







+







    (void)segments;
    (void)nsegments;

    return BadDrawable;
}
#endif

#if 0
char *
XFetchBuffer(
    Display *display,
    int *nbytes_return,
    int buffer)
{
    (void)display;
788
789
790
791
792
793
794

795
796
797
798
799
800
801
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803







+







{
    (void)pts;
    (void)n;
    (void)rule;

    return 0;
}
#endif

void
XDestroyIC(
    XIC ic)
{
    (void)ic;
}
838
839
840
841
842
843
844

845
846
847
848
849
850
851
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854







+







    (void)mask_char;
    (void)foreground_color;
    (void)background_color;

    return (Cursor) NULL;
}

#if 0
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 */
958
959
960
961
962
963
964

965
966
967
968
969
970
971
972
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976







+








XSetIMValues(
    XIM im /* im */, ...
) {
    (void)im;

    return NULL;
}
#endif

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to xlib/ximage.c.
47
48
49
50
51
52
53

54
55
56
57
58






59
60
61
62
63
64
65
47
48
49
50
51
52
53
54





55
56
57
58
59
60
61
62
63
64
65
66
67







+
-
-
-
-
-
+
+
+
+
+
+







    pix = Tk_GetPixmap(display, d, (int) width, (int) height, 1);
    gc = XCreateGC(display, pix, 0, NULL);
    if (gc == NULL) {
	return None;
    }
    ximage = XCreateImage(display, NULL, 1, XYBitmap, 0, (char*) data, width,
	    height, 8, (width + 7) / 8);
    if (ximage) {
    ximage->bitmap_bit_order = LSBFirst;
    _XInitImageFuncPtrs(ximage);
    TkPutImage(NULL, 0, display, pix, gc, ximage, 0, 0, 0, 0, width, height);
    ximage->data = NULL;
    XDestroyImage(ximage);
	ximage->bitmap_bit_order = LSBFirst;
	_XInitImageFuncPtrs(ximage);
	TkPutImage(NULL, 0, display, pix, gc, ximage, 0, 0, 0, 0, width, height);
	ximage->data = NULL;
	XDestroyImage(ximage);
    }
    XFreeGC(display, gc);
    return pix;
}

/*
 * Local Variables:
 * mode: c
Changes to xlib/xutil.c.
28
29
30
31
32
33
34
35
36


37
38
39
40
41
42

43
44
45
46
47
48
49
28
29
30
31
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)
    TCL_UNUSED(_Xconst char *),
    TCL_UNUSED(Bool))
{
    static Atom atom = XA_LAST_PREDEFINED;
    (void)atom_name;
    (void)only_if_exists;

    display->request++;
    LastKnownRequestProcessed(display)++;
    return ++atom;
}

/*
 *----------------------------------------------------------------------
 *
 * XGetVisualInfo --